@@ -13,6 +13,7 @@ import ipBlocker from "./middleware/ipBlock.js";
1313import Razorpay from "razorpay" ;
1414import crypto from "crypto" ;
1515import { paymentService } from "./services/payment.service.js" ;
16+ import { verifyToken } from "./utils/auth.js" ;
1617
1718dotenv . config ( ) ;
1819
@@ -98,6 +99,63 @@ app.get("/test", apiLimiter, (req: Request, res: Response) => {
9899 res . status ( 200 ) . json ( { status : "ok" , message : "Test endpoint is working" } ) ;
99100} ) ;
100101
102+ // Slack Community Invite Endpoint (Protected)
103+ app . get ( "/join-community" , apiLimiter , async ( req : Request , res : Response ) => {
104+ try {
105+ // Get token from Authorization header or query parameter
106+ let token : string | undefined ;
107+ const authHeader = req . headers . authorization ;
108+
109+ if ( authHeader && authHeader . startsWith ( "Bearer " ) ) {
110+ token = authHeader . substring ( 7 ) ; // Remove "Bearer " prefix
111+ } else if ( req . query . token && typeof req . query . token === "string" ) {
112+ token = req . query . token ;
113+ }
114+
115+ if ( ! token ) {
116+ return res . status ( 401 ) . json ( { error : "Unauthorized - Missing token" } ) ;
117+ }
118+
119+ // Verify token and get user
120+ let user ;
121+ try {
122+ user = await verifyToken ( token ) ;
123+ } catch ( error ) {
124+ return res . status ( 401 ) . json ( { error : "Unauthorized - Invalid token" } ) ;
125+ }
126+
127+ // Check if user has an active subscription
128+ const subscription = await prismaModule . prisma . subscription . findFirst ( {
129+ where : {
130+ userId : user . id ,
131+ status : "active" ,
132+ endDate : {
133+ gte : new Date ( ) ,
134+ } ,
135+ } ,
136+ } ) ;
137+
138+ if ( ! subscription ) {
139+ return res . status ( 403 ) . json ( {
140+ error : "Forbidden - Active subscription required to join community" ,
141+ } ) ;
142+ }
143+
144+ // Get Slack invite URL from environment
145+ const slackInviteUrl = process . env . SLACK_INVITE_URL ;
146+ if ( ! slackInviteUrl ) {
147+ console . error ( "SLACK_INVITE_URL not configured" ) ;
148+ return res . status ( 500 ) . json ( { error : "Community invite not configured" } ) ;
149+ }
150+
151+ // Redirect to Slack community
152+ return res . redirect ( slackInviteUrl ) ;
153+ } catch ( error : any ) {
154+ console . error ( "Community invite error:" , error ) ;
155+ return res . status ( 500 ) . json ( { error : "Internal server error" } ) ;
156+ }
157+ } ) ;
158+
101159// Razorpay Webhook Handler (Backup Flow)
102160app . post ( "/webhook/razorpay" , async ( req : Request , res : Response ) => {
103161 try {
0 commit comments