aaspai-authx 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/express/index.ts","../src/express/auth.routes.ts","../src/config/loadConfig.ts","../src/config/index.ts","../src/core/roles.config.ts","../src/core/session.ts","../src/models/rolePermission.model.ts","../src/models/user.model.ts","../src/utils/extract.ts","../src/utils/jwt.ts","../src/middlewares/auth.middleware.ts","../src/middlewares/validators.ts","../src/models/invite.model.ts","../src/services/auth-admin.service.ts","../src/models/client.model.ts","../src/services/email.service.ts","../src/utils/cookie.ts","../src/express/dashboards.routes.ts","../src/express/email.routes.ts","../src/express/projects.routes.ts","../src/services/projects.service.ts","../src/models/moduleConnection.model.ts","../src/models/project.model.ts","../src/express/admin/admin.routes.ts","../src/core/utils.ts","../src/middlewares/requireRole.ts","../src/models/permissions.model.ts","../src/nest/index.ts","../src/middlewares/permission.middleware.ts","../src/middlewares/requirePermission.ts","../src/services/upload.service.ts","../src/nest/authx.guard.ts","../src/nest/decorators/permissions.decorator.ts","../src/nest/decorators/roles.decorator.ts","../src/nest/decorators/session.decorator.ts","../src/passport/authx.strategy.ts","../src/next/server/authx.ts","../src/next/server/withAuthRoute.ts","../src/next/client/AuthXProvider.tsx","../src/next/client/HasPermission.tsx","../src/next/client/HasRole.tsx","../src/next/client/SignedIn.tsx","../src/next/client/SignedOut.tsx","../src/next/client/useAuthX.ts"],"sourcesContent":["export * as express from './express/index.js';\nexport { nest } from './nest/index.js';\n\n// Export types and utilities that might be needed\nexport { authorize, requireAuth } from './middlewares/auth.middleware.js';\nexport { requirePermission as requirePermissionLegacy } from './middlewares/permission.middleware.js';\nexport { requirePermission } from './middlewares/requirePermission.js';\nexport { requireRole } from './middlewares/requireRole.js';\nexport { AuthAdminService } from './services/auth-admin.service.js';\nexport { EmailService } from './services/email.service.js';\nexport { ProjectsService } from './services/projects.service.js';\nexport { UploadsService } from './services/upload.service.js';\n\n// Export core RBAC utilities\nexport { getPermissionsForRoles, PLATFORM_ROLES } from './core/roles.config.js';\nexport { buildSession } from './core/session.js';\nexport {\n hasAllPermissions,\n hasAllRoles,\n hasAnyPermission,\n hasAnyRole,\n hasPermission,\n hasRole,\n} from './core/utils.js';\n\n// Export NestJS components\nexport { AuthXGuard } from './nest/authx.guard.js';\nexport { Permissions } from './nest/decorators/permissions.decorator.js';\nexport { Roles } from './nest/decorators/roles.decorator.js';\nexport { AuthXSessionDecorator } from './nest/decorators/session.decorator.js';\n\n// Export Passport strategy\nexport {\n AuthXStrategy,\n createAuthXStrategy,\n} from './passport/authx.strategy.js';\n\n// Export Next.js server components\nexport { authx } from './next/server/authx.js';\nexport { withAuthRoute } from './next/server/withAuthRoute.js';\n\n// Export Next.js client components\nexport { AuthXProvider, useAuthXContext } from './next/client/AuthXProvider.js';\nexport { HasPermission } from './next/client/HasPermission.js';\nexport { HasRole } from './next/client/HasRole.js';\nexport { SignedIn } from './next/client/SignedIn.js';\nexport { SignedOut } from './next/client/SignedOut.js';\nexport {\n useAuthX,\n useHasPermission,\n useHasRole,\n} from './next/client/useAuthX.js';\n","export { createAuthRouter } from './auth.routes';\r\nexport { createDashboardRouter } from './dashboards.routes';\r\nexport { createEmailRouter } from './email.routes';\r\nexport { createProjectsRouter } from './projects.routes';\r\nexport { createAdminRouter } from './admin/admin.routes';\r\n","import type { AuthRouterOptions } from 'aaspai-types';\r\nimport bcrypt from 'bcryptjs';\r\nimport { randomUUID } from 'crypto';\r\nimport express, { Router, type Router as ExpressRouter } from 'express';\r\nimport jwt from 'jsonwebtoken';\r\nimport { configureAuthX } from '../config/index.js';\r\nimport { requireAuth } from '../middlewares/auth.middleware.js';\r\nimport {\r\n isPasswordStrong,\r\n validateLogin,\r\n validateResendEmail,\r\n validateResetPassword,\r\n validateSendInvite,\r\n validateSignup,\r\n} from '../middlewares/validators.js';\r\nimport { Invite } from '../models/invite.model.js';\r\nimport { OrgUser } from '../models/user.model.js';\r\nimport { AuthAdminService } from '../services/auth-admin.service.js';\r\nimport { EmailService } from '../services/email.service.js';\r\nimport { clearOpts, cookieOpts } from '../utils/cookie.js';\r\n\r\nexport function createAuthRouter(\r\n options: AuthRouterOptions = {},\r\n): ExpressRouter {\r\n if (options.config) {\r\n configureAuthX(options.config);\r\n }\r\n\r\n const r = Router();\r\n\r\n const email = new EmailService();\r\n const authAdmin = new AuthAdminService();\r\n\r\n r.use(express.json());\r\n r.use(express.urlencoded({ extended: true }));\r\n\r\n r.get('/healthz', (_req, res) =>\r\n res.json({ status: 'ok', server: 'org-server' }),\r\n );\r\n\r\n r.post('/login', validateLogin, async (req, res) => {\r\n const { email: emailAddress, password } = req.body || {};\r\n\r\n try {\r\n // 1. Find user in your DB\r\n const user = await OrgUser.findOne({ email: emailAddress })\r\n .select('+password')\r\n .lean();\r\n\r\n if (!user) {\r\n return res.status(400).json({\r\n error: 'Invalid email or password',\r\n code: 'INVALID_CREDENTIALS',\r\n });\r\n }\r\n\r\n // 2. Check if email is verified\r\n if (!user.emailVerified) {\r\n return res.status(400).json({\r\n error: 'Please verify your email before logging in.',\r\n code: 'EMAIL_NOT_VERIFIED',\r\n });\r\n }\r\n\r\n // 3. CRITICAL: Verify password with bcrypt\r\n const isPasswordValid = user.passwordHash\r\n ? await bcrypt.compare(password, user.passwordHash)\r\n : false;\r\n\r\n if (!isPasswordValid) {\r\n return res.status(400).json({\r\n error: 'Invalid email or password',\r\n code: 'INVALID_CREDENTIALS',\r\n });\r\n }\r\n\r\n // 4. Generate tokens\r\n const tokens = generateTokens(user);\r\n setAuthCookies(res, tokens);\r\n\r\n // 5. Set projectId cookie if exists\r\n if (user.projectId) {\r\n res.cookie(options.projectCookieName || 'projectId', user.projectId, {\r\n ...cookieOpts(false),\r\n httpOnly: true,\r\n } as any);\r\n }\r\n\r\n return res.json({\r\n message: 'Login successful',\r\n user: toUserResponse(user),\r\n });\r\n } catch (err: any) {\r\n console.error('Login error:', err);\r\n return res.status(500).json({ error: 'Internal server error' });\r\n }\r\n });\r\n\r\n r.post('/signup', validateSignup, async (req, res) => {\r\n const {\r\n firstName,\r\n lastName,\r\n email: emailAddress,\r\n password,\r\n projectId,\r\n metadata,\r\n } = req.body || {};\r\n\r\n try {\r\n const kcUser = await authAdmin.createUserInRealm({\r\n username: emailAddress,\r\n email: emailAddress,\r\n firstName,\r\n lastName,\r\n projectId,\r\n credentials: [{ type: 'password', value: password, temporary: false }],\r\n });\r\n\r\n await authAdmin.assignRealmRole(kcUser.id, 'platform_user');\r\n\r\n const user = await OrgUser.findOneAndUpdate(\r\n { email: kcUser.email },\r\n {\r\n id: kcUser.id,\r\n email: kcUser.email,\r\n firstName,\r\n lastName,\r\n projectId,\r\n metadata,\r\n roles: ['platform_user'],\r\n emailVerified: false,\r\n },\r\n { upsert: true, new: true, setDefaultsOnInsert: true },\r\n );\r\n\r\n const emailResult = await sendRateLimitedEmail({\r\n emailService: email,\r\n user,\r\n subject: 'Verify your email',\r\n html: buildVerificationTemplate(\r\n email.sign({ userId: kcUser.id, email: kcUser.email }),\r\n options,\r\n ),\r\n });\r\n\r\n if (emailResult.rateLimited) {\r\n return res.status(429).json({\r\n ok: false,\r\n error: 'Too many verification emails sent. Please try again later.',\r\n waitMs: emailResult.waitMs,\r\n });\r\n }\r\n\r\n return res.json({\r\n id: user.id,\r\n email: user.email,\r\n message: 'Verification email sent. Please check your inbox.',\r\n });\r\n } catch (err: any) {\r\n return respondWithKeycloakError(res, err, 'Signup failed');\r\n }\r\n });\r\n\r\n r.get('/me', requireAuth(), (req, res) => {\r\n return res.json((req as any).user || null);\r\n });\r\n\r\n r.post('/logout', async (_req, res) => {\r\n res.clearCookie('access_token', clearOpts() as any);\r\n res.clearCookie('refresh_token', clearOpts() as any);\r\n res.json({ ok: true });\r\n });\r\n\r\n r.put('/:userId/metadata', requireAuth(), async (req, res) => {\r\n const { userId } = req.params as any;\r\n const { metadata } = req.body || {};\r\n\r\n const user = await OrgUser.findOne({ id: userId });\r\n\r\n if (!user)\r\n return res.status(404).json({ ok: false, error: 'User not found' });\r\n\r\n const map = new Map<string, any>(\r\n ((user as any).metadata || []).map((m: any) => [m.key, m.value]),\r\n );\r\n\r\n for (const item of metadata || []) map.set(item.key, item.value);\r\n (user as any).metadata = Array.from(map.entries()).map(([key, value]) => ({\r\n key,\r\n value,\r\n }));\r\n\r\n await (user as any).save();\r\n res.json({ ok: true, metadata: (user as any).metadata });\r\n });\r\n\r\n r.get('/verify-email', async (req, res) => {\r\n const token = String(req.query.token || '');\r\n if (!token) {\r\n return res.status(400).json({ error: 'Verification token is required' });\r\n }\r\n try {\r\n const payload = email.verify<{ email: string; userId: string }>(token);\r\n await authAdmin.updateUserEmailVerified(payload.userId, true);\r\n await OrgUser.updateOne(\r\n { id: payload.userId },\r\n { $set: { emailVerified: true } },\r\n );\r\n res.json({ ok: true, message: 'Email verified' });\r\n } catch (err: any) {\r\n res\r\n .status(400)\r\n .json({ ok: false, error: err?.message || 'Invalid token' });\r\n }\r\n });\r\n\r\n r.post(\r\n '/resend-verification-email',\r\n validateResendEmail,\r\n async (req, res) => {\r\n const user = await OrgUser.findOne({ email: req.body.email });\r\n if (!user)\r\n return res.status(404).json({ ok: false, error: 'User not found' });\r\n\r\n const verified = await authAdmin.isUserEmailVerified(user.id);\r\n if (verified) {\r\n return res\r\n .status(400)\r\n .json({ ok: false, error: 'Email is already verified' });\r\n }\r\n\r\n const token = email.sign({\r\n email: user.email,\r\n userId: user.id,\r\n });\r\n\r\n const resendResult = await sendRateLimitedEmail({\r\n emailService: email,\r\n user,\r\n subject: 'Verify your email',\r\n html: buildVerificationTemplate(token, options),\r\n });\r\n\r\n if (resendResult.rateLimited) {\r\n return res.status(429).json({\r\n ok: false,\r\n error: 'Too many verification emails sent. Please try again later.',\r\n waitMs: resendResult.waitMs,\r\n });\r\n }\r\n\r\n res.json({ ok: true });\r\n },\r\n );\r\n\r\n r.post('/forgot-password', validateResendEmail, async (req, res) => {\r\n const user = await OrgUser.findOne({ email: req.body.email });\r\n if (!user)\r\n return res.status(404).json({ ok: false, error: 'User not found' });\r\n\r\n const resetToken = email.sign(\r\n {\r\n userId: user.id,\r\n email: user.email,\r\n firstName: user.firstName,\r\n lastName: user.lastName,\r\n },\r\n 60 * 60,\r\n );\r\n\r\n const resetResult = await sendRateLimitedEmail({\r\n emailService: email,\r\n user,\r\n subject: 'Reset password',\r\n html: buildResetTemplate(resetToken, options),\r\n });\r\n\r\n if (resetResult.rateLimited) {\r\n return res.status(429).json({\r\n ok: false,\r\n error: 'Please wait before requesting another password reset email.',\r\n waitMs: resetResult.waitMs,\r\n });\r\n }\r\n\r\n res.json({ ok: true, message: 'Password reset email sent' });\r\n });\r\n\r\n r.post('/reset-password', validateResetPassword, async (req, res) => {\r\n const { token, newPassword } = (req.body || {}) as any;\r\n try {\r\n const payload = email.verify<{\r\n userId: string;\r\n email: string;\r\n iat: number;\r\n }>(token);\r\n\r\n const user = await OrgUser.findOne({ keycloakId: payload.userId });\r\n if (!user) {\r\n return res.status(404).json({ ok: false, error: 'User not found' });\r\n }\r\n\r\n if (\r\n user.lastPasswordReset &&\r\n payload.iat * 1000 < user.lastPasswordReset.getTime()\r\n ) {\r\n return res.status(400).json({\r\n ok: false,\r\n error:\r\n 'This reset link has already been used. Please request a new one.',\r\n });\r\n }\r\n\r\n await authAdmin.updateUserPassword(payload.userId, newPassword);\r\n\r\n user.lastPasswordReset = new Date();\r\n await user.save();\r\n\r\n res.json({ ok: true, message: 'Password updated successfully' });\r\n } catch (err: any) {\r\n res\r\n .status(400)\r\n .json({ ok: false, error: err?.message || 'Invalid or expired token' });\r\n }\r\n });\r\n\r\n r.post(\r\n '/send-invite',\r\n requireAuth(),\r\n validateSendInvite,\r\n async (req, res) => {\r\n const { email: emailAddress, role } = req.body || {};\r\n\r\n const existingUser = await OrgUser.findOne({ email: emailAddress });\r\n if (existingUser) {\r\n return res\r\n .status(400)\r\n .json({ ok: false, error: 'User with this email already exists' });\r\n }\r\n\r\n const existingInvite = await Invite.findOne({\r\n email: emailAddress,\r\n isUsed: false,\r\n isExpired: false,\r\n });\r\n\r\n if (existingInvite) {\r\n return res.status(400).json({\r\n ok: false,\r\n error: 'An active invite already exists for this email',\r\n });\r\n }\r\n\r\n const token = email.sign({\r\n email: emailAddress,\r\n role,\r\n inviteId: randomUUID(),\r\n });\r\n\r\n const invite = await Invite.create({\r\n id: token,\r\n email: emailAddress,\r\n role,\r\n invitedBy: (req as any).user?.sub,\r\n isUsed: false,\r\n expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),\r\n });\r\n\r\n await email.send(\r\n emailAddress,\r\n 'You are invited',\r\n `<a href=\"${getFrontendBaseUrl(options)}/auth/accept-invite?token=${token}\">Accept</a>`,\r\n );\r\n\r\n res.json({\r\n ok: true,\r\n inviteId: invite.id,\r\n email: invite.email,\r\n role: invite.role,\r\n expiresAt: invite.expiresAt,\r\n });\r\n },\r\n );\r\n\r\n r.get('/accept-invite', async (req, res) => {\r\n const inv = await Invite.findOne({ id: String(req.query.token) });\r\n res.json({ ok: !!inv && !(inv as any).isUsed && !(inv as any).isExpired });\r\n });\r\n\r\n r.post('/accept-invite', async (req, res) => {\r\n const { token, firstName, lastName, password, projectId } = req.body || {};\r\n\r\n if (\r\n !token ||\r\n !firstName ||\r\n !lastName ||\r\n !isPasswordStrong(password || '')\r\n ) {\r\n return res.status(400).json({ ok: false, error: 'Invalid payload' });\r\n }\r\n\r\n const invite = await Invite.findOne({\r\n id: token,\r\n isUsed: false,\r\n isExpired: false,\r\n });\r\n\r\n if (!invite) {\r\n return res\r\n .status(400)\r\n .json({ ok: false, error: 'Invitation not found or already used' });\r\n }\r\n\r\n if (invite.expiresAt && invite.expiresAt.getTime() < Date.now()) {\r\n invite.isExpired = true;\r\n await invite.save();\r\n return res\r\n .status(400)\r\n .json({ ok: false, error: 'Invitation has expired' });\r\n }\r\n\r\n try {\r\n const kcUser = await authAdmin.createUserInRealm({\r\n username: invite.email,\r\n email: invite.email,\r\n firstName,\r\n lastName,\r\n projectId,\r\n emailVerified: true,\r\n credentials: [{ type: 'password', value: password, temporary: false }],\r\n });\r\n\r\n await authAdmin.assignRealmRole(kcUser.id, invite.role);\r\n\r\n await OrgUser.findOneAndUpdate(\r\n { email: invite.email },\r\n {\r\n id: kcUser.id,\r\n email: invite.email,\r\n firstName,\r\n lastName,\r\n roles: [invite.role],\r\n emailVerified: true,\r\n },\r\n { upsert: true, new: true, setDefaultsOnInsert: true },\r\n );\r\n\r\n invite.isUsed = true;\r\n invite.usedAt = new Date();\r\n invite.usedBy = kcUser.id;\r\n await invite.save();\r\n\r\n res.json({\r\n ok: true,\r\n message: 'Account created successfully.',\r\n email: invite.email,\r\n });\r\n } catch (err: any) {\r\n res.status(400).json({\r\n ok: false,\r\n error:\r\n err?.response?.data?.error_description ||\r\n err?.message ||\r\n 'Failed to create account',\r\n });\r\n }\r\n });\r\n\r\n r.get('/invites', requireAuth(), async (_req, res) => {\r\n const invites = await Invite.find().sort({ createdAt: -1 }).lean();\r\n res.json(invites);\r\n });\r\n\r\n r.delete('/invites/:inviteId', requireAuth(), async (req, res) => {\r\n await Invite.deleteOne({ id: req.params.inviteId });\r\n res.json({ ok: true });\r\n });\r\n\r\n r.get('/get-user-by-email', async (req, res) => {\r\n const user = await OrgUser.findOne({ email: req.query.email }).lean();\r\n res.json(user || null);\r\n });\r\n\r\n r.get('/google', async (_req, res) => {\r\n res.json({ url: '/auth/google/callback?code=demo' });\r\n });\r\n\r\n r.get('/google/callback', async (_req, res) => {\r\n res.cookie(\r\n 'access_token',\r\n 'ACCESS.TOKEN.PLACEHOLDER',\r\n cookieOpts(false) as any,\r\n );\r\n res.redirect('/');\r\n });\r\n\r\n r.get('/get-users', async (req, res) => {\r\n const user = await OrgUser.find({ projectId: req.query.projectId }).lean();\r\n res.json(user || null);\r\n });\r\n\r\n return r;\r\n}\r\n\r\nfunction setAuthCookies(res: any, tokens: any) {\r\n if (tokens?.access_token) {\r\n res.cookie('access_token', tokens.access_token, {\r\n httpOnly: true,\r\n secure: false,\r\n sameSite: 'lax',\r\n maxAge: 24 * 60 * 60 * 1000, // 24 hours\r\n path: '/',\r\n });\r\n }\r\n if (tokens?.refresh_token) {\r\n res.cookie('refresh_token', tokens.refresh_token, {\r\n httpOnly: true,\r\n secure: false,\r\n sameSite: 'lax',\r\n maxAge: 24 * 60 * 60 * 1000, // 24 hours\r\n path: '/',\r\n });\r\n }\r\n}\r\n\r\nfunction toUserResponse(user: any) {\r\n if (!user) return null;\r\n return {\r\n sub: user.id || user.keycloakId,\r\n email: user.email,\r\n firstName: user.firstName,\r\n lastName: user.lastName,\r\n projectId: user.projectId,\r\n metadata: user.metadata,\r\n roles: user.roles,\r\n };\r\n}\r\n\r\nfunction respondWithKeycloakError(\r\n res: any,\r\n err: any,\r\n fallback: string,\r\n status = 400,\r\n) {\r\n const description =\r\n err?.response?.data?.error_description ||\r\n err?.response?.data?.errorMessage ||\r\n err?.message ||\r\n fallback;\r\n return res.status(status).json({ ok: false, error: description });\r\n}\r\n\r\nfunction buildVerificationTemplate(token: string, options: AuthRouterOptions) {\r\n return `<a href=\"${getFrontendBaseUrl(options)}/auth/verify-email?token=${token}\">Verify</a>`;\r\n}\r\n\r\nfunction buildResetTemplate(token: string, options: AuthRouterOptions) {\r\n return `<a href=\"${getFrontendBaseUrl(options)}/auth/reset-password?token=${token}\">Reset</a>`;\r\n}\r\n\r\nfunction getFrontendBaseUrl(options: AuthRouterOptions) {\r\n if (options.frontendBaseUrl)\r\n return options.frontendBaseUrl.replace(/\\/$/, '');\r\n const domain = process.env.ORG_DOMAIN!?.replace(/\\/$/, '');\r\n if (!domain) return '';\r\n return domain.startsWith('http') ? domain : `https://${domain}`;\r\n}\r\n\r\nasync function sendRateLimitedEmail({\r\n emailService,\r\n user,\r\n subject,\r\n html,\r\n}: {\r\n emailService: EmailService;\r\n user: any;\r\n subject: string;\r\n html: string;\r\n}): Promise<{ rateLimited: boolean; waitMs?: number }> {\r\n const can = emailService.canSend(user?.lastEmailSent || []);\r\n if (!can.ok) {\r\n return { rateLimited: true, waitMs: (can as any).waitMs };\r\n }\r\n\r\n await emailService.send(user.email, subject, html);\r\n user.lastEmailSent = [...(user.lastEmailSent || []), new Date()];\r\n await user.save();\r\n return { rateLimited: false };\r\n}\r\n\r\nfunction generateTokens(user: any) {\r\n const accessPayload = {\r\n sub: user.id.toString(),\r\n email: user.email,\r\n roles: user.roles || [],\r\n orgId: user.orgId || null,\r\n org_id: user.orgId || null,\r\n projectId: user.projectId || null,\r\n type: 'user',\r\n };\r\n\r\n const accessToken = jwt.sign(accessPayload, process.env.JWT_SECRET!, {\r\n expiresIn: '1h',\r\n });\r\n\r\n const refreshToken = jwt.sign(\r\n { sub: user._id.toString() },\r\n process.env.JWT_SECRET!,\r\n { expiresIn: '30d' },\r\n );\r\n\r\n return { access_token: accessToken, refresh_token: refreshToken };\r\n}\r\n","import type {\n AuthXConfig,\n AwsConfig,\n CookieConfig,\n EmailConfig,\n OidcConfig,\n} from 'aaspai-types';\n\nexport function loadConfig(): AuthXConfig {\n return {\n orgDomain: process.env.ORG_DOMAIN!,\n orgId: process.env.ORG_ID!,\n email: {\n host: process.env.EMAIL_HOST || 'smtp.postmarkapp.com',\n port: process.env.EMAIL_PORT ? Number(process.env.EMAIL_PORT) : 587,\n secure: (process.env.EMAIL_SECURE || 'false') === 'true',\n user: process.env.EMAIL_USER!,\n pass: process.env.EMAIL_PASSWORD!,\n from: process.env.EMAIL_FROM!,\n jwtSecret: process.env.EMAIL_JWT_SECRET!,\n } as EmailConfig,\n cookies: {\n domain: process.env.COOKIE_DOMAIN!,\n secure: (process.env.COOKIE_SECURE || 'true') === 'true',\n accessTtlMs: 24 * 60 * 60 * 1000,\n refreshTtlMs: 7 * 24 * 60 * 60 * 1000,\n } as CookieConfig,\n oidc: {\n jwtSecret: process.env.JWT_SECRET!,\n } as OidcConfig,\n aws: {\n bucket: process.env.AWS_S3_BUCKET!,\n region: process.env.AWS_REGION!,\n accessKeyId: process.env.AWS_ACCESS_KEY_ID!,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,\n } as AwsConfig,\n };\n}\n","import type {\n AuthXConfig,\n AwsConfig,\n CookieConfig,\n DeepPartial,\n EmailConfig,\n OidcConfig,\n} from 'aaspai-types';\nimport { loadConfig } from './loadConfig.js';\n\nexport type {\n AuthXConfig,\n AwsConfig,\n CookieConfig,\n DeepPartial,\n EmailConfig,\n OidcConfig,\n};\n\nexport const config: AuthXConfig = loadConfig();\n\nexport function configureAuthX(\n overrides: DeepPartial<AuthXConfig> = {},\n): AuthXConfig {\n return deepMerge(config, overrides);\n}\n\nexport function getConfig(): AuthXConfig {\n return config;\n}\n\nfunction deepMerge<T extends Record<string, any>>(\n target: T,\n source: DeepPartial<T>,\n): T {\n if (!source) {\n return target;\n }\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const value = source[key];\n if (value === undefined) continue;\n\n if (Array.isArray(value)) {\n (target as any)[key] = [...value];\n continue;\n }\n\n if (isPlainObject(value)) {\n if (!isPlainObject(target[key])) {\n (target as any)[key] = {};\n }\n deepMerge(target[key] as Record<string, any>, value as any);\n continue;\n }\n\n (target as any)[key] = value;\n }\n\n return target;\n}\n\nfunction isPlainObject(value: any): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","export const PLATFORM_ROLES = [\r\n {\r\n role: 'platform_admin',\r\n permissions: [],\r\n },\r\n {\r\n role: 'platform_manager',\r\n permissions: [],\r\n },\r\n {\r\n role: 'platform_user',\r\n permissions: [],\r\n },\r\n];\r\n\r\n/**\r\n * Get all permissions for a given set of roles\r\n * @param roles - Array of role names\r\n * @returns Array of unique permission strings\r\n */\r\nexport function getPermissionsForRoles(roles: string[]): string[] {\r\n if (!Array.isArray(roles) || roles.length === 0) {\r\n return [];\r\n }\r\n\r\n const permissionSet = new Set<string>();\r\n\r\n for (const roleName of roles) {\r\n const roleConfig = PLATFORM_ROLES.find((r) => r.role === roleName);\r\n if (roleConfig && Array.isArray(roleConfig.permissions)) {\r\n for (const perm of roleConfig.permissions) {\r\n permissionSet.add(perm);\r\n }\r\n }\r\n }\r\n\r\n return Array.from(permissionSet);\r\n}\r\n","import type { AuthXSession } from 'aaspai-types';\r\nimport { getPermissionsForRoles } from './roles.config.js';\r\n\r\n/**\r\n * Build a canonical AuthXSession from a JWT payload or user object\r\n * @param payload - JWT payload or user object from existing auth middleware\r\n * @returns AuthXSession with standardized shape\r\n */\r\nexport function buildSession(payload: any): AuthXSession {\r\n // Extract user ID (sub is standard JWT claim)\r\n const userId = payload?.sub || payload?.userId || payload?.id || '';\r\n\r\n // Extract email\r\n const email = payload?.email || payload?.email_address || '';\r\n\r\n // Extract roles from various possible locations\r\n const roles =\r\n payload?.realm_access?.roles ||\r\n payload?.roles ||\r\n payload?.['cognito:groups'] ||\r\n (Array.isArray(payload?.role) ? payload.role : []) ||\r\n [];\r\n\r\n // Ensure roles is an array of strings\r\n const normalizedRoles = Array.isArray(roles)\r\n ? roles.map(String).filter(Boolean)\r\n : [];\r\n\r\n // Derive permissions from roles using PLATFORM_ROLES config\r\n const permissions = getPermissionsForRoles(normalizedRoles);\r\n\r\n // Build base session\r\n const session: AuthXSession = {\r\n userId,\r\n email,\r\n roles: normalizedRoles,\r\n permissions,\r\n };\r\n\r\n // Preserve optional fields if present\r\n if (payload?.projectId) session.projectId = payload.projectId;\r\n if (payload?.orgId) session.orgId = payload.orgId;\r\n if (payload?.org_id) session.org_id = payload.org_id;\r\n if (payload?.authType) session.authType = payload.authType;\r\n\r\n // Preserve any other custom fields\r\n Object.keys(payload || {}).forEach((key) => {\r\n if (\r\n ![\r\n 'sub',\r\n 'userId',\r\n 'id',\r\n 'email',\r\n 'email_address',\r\n 'realm_access',\r\n 'roles',\r\n 'cognito:groups',\r\n 'role',\r\n 'projectId',\r\n 'orgId',\r\n 'org_id',\r\n 'authType',\r\n ].includes(key)\r\n ) {\r\n session[key] = payload[key];\r\n }\r\n });\r\n\r\n return session;\r\n}\r\n","// src/models/rolePermission.model.ts\r\nimport mongoose, { Document, Schema } from 'mongoose';\r\n\r\nexport interface RolePermissionDocument extends Document {\r\n orgId?: string | null; // null => platform-wide\r\n role: string; // \"platform_admin\", \"platform_manager\", \"custom_role\"\r\n permissions: string[]; // list of permission keys\r\n createdAt: Date;\r\n updatedAt: Date;\r\n}\r\n\r\nconst RolePermissionSchema = new Schema<RolePermissionDocument>(\r\n {\r\n orgId: { type: String, default: null, index: true },\r\n role: { type: String, required: true },\r\n permissions: { type: [String], default: [] },\r\n },\r\n {\r\n timestamps: true,\r\n },\r\n);\r\n\r\nRolePermissionSchema.index({ orgId: 1, role: 1 }, { unique: true });\r\n\r\nexport const RolePermissionModel = mongoose.model<RolePermissionDocument>(\r\n 'RolePermission',\r\n RolePermissionSchema,\r\n 'role_permissions',\r\n);\r\n","import mongoose from 'mongoose';\nimport { v4 as uuid } from 'uuid';\n\nconst MetadataSchema = new mongoose.Schema(\n {\n key: { type: String, required: true },\n value: { type: mongoose.Schema.Types.Mixed, required: true },\n },\n { _id: false },\n);\n\nconst OrgUserSchema = new mongoose.Schema(\n {\n id: { type: String, default: uuid(), index: true },\n email: { type: String, required: true, unique: true },\n firstName: { type: String, required: true },\n lastName: { type: String, required: true },\n orgId: { type: String },\n projectId: { type: String, required: true },\n roles: { type: [String], default: [] },\n emailVerified: { type: Boolean, default: false },\n lastEmailSent: { type: [Date], default: [] },\n lastPasswordReset: { type: Date },\n metadata: { type: [MetadataSchema], default: [] },\n passwordHash: { type: String },\n },\n { timestamps: true, collection: 'users' },\n);\n\nexport const OrgUser = mongoose.model('OrgUser', OrgUserSchema);\n","import { parse as parseCookie } from 'cookie';\nimport type { Request } from 'express';\n\nexport function extractToken(\n req: Request,\n opts?: {\n headerNames?: string[];\n cookieNames?: string[];\n queryNames?: string[];\n },\n) {\n const headerNames = opts?.headerNames ?? ['authorization', 'token'];\n const cookieNames = opts?.cookieNames ?? ['access_token', 'authorization'];\n const queryNames = opts?.queryNames ?? ['access_token', 'token'];\n\n for (const h of headerNames) {\n const raw = (req.headers as any)[h] as string | undefined;\n if (raw) {\n const lower = raw.toLowerCase();\n if (lower.startsWith('bearer ')) return raw.slice(7).trim();\n if (!raw.includes(' ')) return raw.trim();\n }\n }\n\n const ch = req.headers['cookie'];\n\n if (typeof ch === 'string') {\n const parsed = parseCookie(ch);\n for (const c of cookieNames) if (parsed[c]) return parsed[c];\n }\n\n for (const q of queryNames) {\n const v = (req.query as any)?.[q];\n if (typeof v === 'string' && v) return v;\n }\n\n return null;\n}\n\nexport function readProjectId(req: Request) {\n const ch = req.headers['cookie'];\n\n if (typeof ch === 'string') {\n try {\n const parsed = parseCookie(ch);\n return parsed['projectId'] || null;\n } catch {}\n }\n\n return null;\n}\n","import jwt from 'jsonwebtoken';\nimport { config } from '../config/index.js';\n\nexport function verifyJwt(token: string): Promise<any> {\n return new Promise((resolve, reject) => {\n jwt.verify(\n token,\n process.env.JWT_SECRET!, // This is your shared secret (string)\n {\n algorithms: ['HS256'], // Only allow HS256\n complete: false, // We only want payload\n },\n (err, decoded) => {\n if (err) {\n reject(err);\n } else {\n resolve(decoded);\n }\n },\n );\n });\n}\n\nexport function claimsToUser(payload: any) {\n return {\n sub: payload.sub,\n email: payload.email || payload.preferred_username,\n roles: payload.roles || [],\n name:\n payload.name ||\n `${payload.given_name || ''} ${payload.family_name || ''}`.trim(),\n emailVerified: payload.email_verified || false,\n };\n}\n","import type { AuthXSession } from 'aaspai-types';\r\nimport type { NextFunction, Request, Response } from 'express';\r\nimport { buildSession } from '../core/session.js';\r\nimport { RolePermissionModel } from '../models/rolePermission.model.js';\r\nimport { OrgUser } from '../models/user.model.js';\r\nimport { extractToken, readProjectId } from '../utils/extract.js';\r\nimport { verifyJwt } from '../utils/jwt.js';\r\n\r\nasync function mergeRolePermissions(session: AuthXSession): Promise<void> {\r\n const roles = Array.isArray(session.roles) ? session.roles : [];\r\n if (!roles.length) return;\r\n\r\n const orgContexts = new Set<string | null>();\r\n if (session.orgId) orgContexts.add(session.orgId);\r\n if (session.org_id) orgContexts.add(session.org_id);\r\n if (session.projectId) orgContexts.add(session.projectId);\r\n orgContexts.add(null);\r\n\r\n const docs = await RolePermissionModel.find({\r\n orgId: { $in: Array.from(orgContexts) },\r\n role: { $in: roles },\r\n })\r\n .lean()\r\n .exec();\r\n\r\n const dynamic = new Set<string>();\r\n for (const doc of docs) {\r\n for (const perm of doc.permissions || []) {\r\n if (perm) dynamic.add(perm);\r\n }\r\n }\r\n\r\n const existing = Array.isArray(session.permissions) ? session.permissions : [];\r\n session.permissions = Array.from(new Set([...existing, ...dynamic]));\r\n}\r\n\r\n/**\r\n * Express middleware to require authentication\r\n * Extracts and verifies JWT token, builds AuthXSession, and attaches to req.user\r\n */\r\nexport function requireAuth() {\r\n return async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n // Check for API key first (for backward compatibility)\r\n const apiKey = (req.headers['x-api-key'] || req.headers['x-apikey']) as\r\n | string\r\n | undefined;\r\n\r\n const userId = (req.headers['x-user-id'] || req.headers['x-userId']) as\r\n | string\r\n | undefined;\r\n\r\n if (apiKey) {\r\n if (apiKey !== process.env.SERVER_API_KEY) {\r\n return res.status(401).json({ error: 'Invalid API key' });\r\n }\r\n\r\n if (!userId) {\r\n return res.status(401).json({ error: 'User Id is Required' });\r\n }\r\n\r\n // Fetch real user from DB\r\n const user = await OrgUser.findOne({ id: userId }).lean();\r\n\r\n if (!user) {\r\n return res.status(401).json({ error: 'User not found' });\r\n }\r\n\r\n const session = buildSession({\r\n sub: user.id.toString(),\r\n email: user.email,\r\n roles: user.roles || [],\r\n orgId: user.orgId,\r\n org_id: user.orgId,\r\n projectId: user.projectId,\r\n });\r\n\r\n session.authType = 'api-key';\r\n session.projectId = readProjectId(req) || user.projectId || undefined;\r\n await mergeRolePermissions(session);\r\n (req as any).user = session;\r\n return next();\r\n } else {\r\n // Extract and verify JWT token\r\n const token = extractToken(req);\r\n if (!token) {\r\n return res.status(401).json({ error: 'Missing token' });\r\n }\r\n const claims = await verifyJwt(token);\r\n const session = buildSession(claims);\r\n // Preserve projectId if present in cookie\r\n const pid = readProjectId(req);\r\n if (pid) session.projectId = pid;\r\n await mergeRolePermissions(session);\r\n\r\n // Attach session to request\r\n (req as any).user = session;\r\n next();\r\n }\r\n } catch (e: any) {\r\n res.status(401).json({ error: e?.message || 'Unauthorized' });\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Express middleware to require one or more roles\r\n * @param roles - Array of role names (user must have at least one)\r\n * @deprecated Use requireRole from middlewares instead. This is kept for backward compatibility.\r\n */\r\nexport function authorize(roles: string[] = []) {\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n if (!roles || roles.length === 0) return next();\r\n const user = (req as any).user as AuthXSession | undefined;\r\n if (!user) {\r\n return res.status(401).json({ error: 'Unauthorized' });\r\n }\r\n const have = new Set<string>((user.roles || []).map(String));\r\n const ok = roles.some((r) => have.has(r));\r\n if (!ok) {\r\n return res\r\n .status(403)\r\n .json({ error: `Requires one of roles: ${roles.join(', ')}` });\r\n }\r\n next();\r\n };\r\n}\r\n","export function isEmail(v: string) {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(v);\n}\n\nexport function isPasswordStrong(v: string) {\n return (\n typeof v === 'string' &&\n v.length >= 6 &&\n /[A-Z]/.test(v) &&\n /[^a-zA-Z0-9]/.test(v)\n );\n}\n\nexport function validateSignup(req: any, res: any, next: any) {\n const { firstName, lastName, email, password, projectId, metadata } =\n req.body || {};\n if (!firstName || !lastName)\n return res.status(400).json({ error: 'firstName,lastName required' });\n if (!isEmail(email)) return res.status(400).json({ error: 'invalid email' });\n if (!isPasswordStrong(password))\n return res.status(400).json({ error: 'weak password' });\n if (!projectId) return res.status(400).json({ error: 'projectId required' });\n if (!Array.isArray(metadata))\n return res.status(400).json({ error: 'metadata must be array' });\n next();\n}\n\nexport function validateLogin(req: any, res: any, next: any) {\n const { email, password } = req.body || {};\n if (!isEmail(email)) return res.status(400).json({ error: 'invalid email' });\n if (typeof password !== 'string')\n return res.status(400).json({ error: 'password required' });\n next();\n}\n\nexport function validateResetPassword(req: any, res: any, next: any) {\n const { token, newPassword } = req.body || {};\n if (!token) return res.status(400).json({ error: 'token required' });\n if (!isPasswordStrong(newPassword))\n return res.status(400).json({ error: 'weak password' });\n next();\n}\n\nexport function validateResendEmail(req: any, res: any, next: any) {\n const { email } = req.body || {};\n if (!isEmail(email)) return res.status(400).json({ error: 'invalid email' });\n next();\n}\n\nexport function validateSendInvite(req: any, res: any, next: any) {\n const { email, role } = req.body || {};\n if (!isEmail(email)) return res.status(400).json({ error: 'invalid email' });\n if (!['platform_user', 'org_admin'].includes(role))\n return res.status(400).json({ error: 'invalid role' });\n next();\n}\n","import mongoose from 'mongoose';\n\nconst InviteSchema = new mongoose.Schema(\n {\n id: { type: String, required: true, index: true },\n email: { type: String, required: true },\n role: {\n type: String,\n enum: ['platform_user', 'org_admin'],\n required: true,\n },\n invitedBy: { type: String },\n usedBy: { type: String },\n isUsed: { type: Boolean, default: false },\n usedAt: { type: Date },\n expiresAt: { type: Date },\n isExpired: { type: Boolean, default: false },\n },\n { timestamps: true, collection: 'invites' },\n);\n\nexport const Invite = mongoose.model('Invite', InviteSchema);\n","import bcrypt from 'bcrypt';\r\nimport jwt from 'jsonwebtoken';\r\nimport { config } from '../config/index.js';\r\nimport { ClientModel } from '../models/client.model.js';\r\nimport { RolePermissionModel } from '../models/rolePermission.model.js';\r\nimport { OrgUser } from '../models/user.model.js';\r\n\r\nexport class AuthAdminService {\r\n private token?: { accessToken: string; exp: number };\r\n\r\n async getAdminToken() {\r\n return this.ensureAdminToken();\r\n }\r\n\r\n // -------------------------------------------------------------------\r\n // CLIENTS\r\n // -------------------------------------------------------------------\r\n async createClient(\r\n clientId: string,\r\n redirectUris: string[] = [],\r\n publicClient = false,\r\n ) {\r\n const client = await ClientModel.create({\r\n clientId,\r\n redirectUris,\r\n publicClient,\r\n });\r\n return client;\r\n }\r\n\r\n async updateClient(id: string, patch: any) {\r\n await ClientModel.findByIdAndUpdate(id, patch);\r\n }\r\n\r\n // -------------------------------------------------------------------\r\n // USERS\r\n // -------------------------------------------------------------------\r\n async listUsersInRealm(\r\n _realm: string,\r\n filter?: { email?: string; username?: string },\r\n ) {\r\n return OrgUser.find(filter || {});\r\n }\r\n\r\n async getUserById(userId: string) {\r\n return OrgUser.findOne({ id: userId });\r\n }\r\n\r\n async isUserEmailVerified(userId: string) {\r\n const user: any = await OrgUser.findOne({ id: userId });\r\n return user?.emailVerified;\r\n }\r\n\r\n async createUserInRealm(payload: {\r\n username: string;\r\n email: string;\r\n firstName: string;\r\n projectId: string;\r\n lastName?: string;\r\n credentials?: any[];\r\n emailVerified?: boolean;\r\n }) {\r\n const hashedPassword = payload.credentials?.[0]?.value\r\n ? await bcrypt.hash(payload.credentials[0].value, 10)\r\n : undefined;\r\n\r\n const user = await OrgUser.create({\r\n username: payload.username,\r\n email: payload.email,\r\n firstName: payload.firstName,\r\n lastName: payload.lastName,\r\n projectId: payload.projectId,\r\n emailVerified: payload.emailVerified || false,\r\n passwordHash: hashedPassword,\r\n enabled: true,\r\n });\r\n\r\n return user;\r\n }\r\n\r\n async assignRealmRole(userId: string, roleName: string) {\r\n const role = await RolePermissionModel.findOne({ name: roleName });\r\n if (!role) throw new Error(`Role not found: ${roleName}`);\r\n\r\n await OrgUser.findOneAndUpdate(\r\n { id: userId },\r\n {\r\n $addToSet: { roles: role._id },\r\n },\r\n );\r\n }\r\n\r\n async updateUserEmailVerified(userId: string, emailVerified: boolean) {\r\n await OrgUser.findOneAndUpdate({ id: userId }, { emailVerified });\r\n }\r\n\r\n async updateUserPassword(userId: string, newPassword: string) {\r\n const hashed = await bcrypt.hash(newPassword, 10);\r\n await OrgUser.findOneAndUpdate({ id: userId }, { password: hashed });\r\n }\r\n\r\n // -------------------------------------------------------------------\r\n // ADMIN TOKEN (self-issued JWT)\r\n // -------------------------------------------------------------------\r\n private async ensureAdminToken(): Promise<string> {\r\n const now = Math.floor(Date.now() / 1000);\r\n\r\n if (this.token && this.token.exp - 30 > now) {\r\n return this.token.accessToken;\r\n }\r\n\r\n const payload = {\r\n type: 'admin',\r\n system: true,\r\n };\r\n\r\n const accessToken = jwt.sign(payload, process.env.JWT_SECRET!, {\r\n expiresIn: '1h',\r\n });\r\n\r\n this.token = {\r\n accessToken,\r\n exp: now + 3600,\r\n };\r\n\r\n return this.token.accessToken;\r\n }\r\n}\r\n","import mongoose, { Document, Model, Schema } from 'mongoose';\r\n\r\nexport interface IClient extends Document {\r\n clientId: string;\r\n redirectUris: string[];\r\n publicClient: boolean;\r\n secret?: string; // optional — used only for confidential clients\r\n createdAt: Date;\r\n updatedAt: Date;\r\n}\r\n\r\nconst ClientSchema = new Schema<IClient>(\r\n {\r\n clientId: {\r\n type: String,\r\n required: true,\r\n unique: true,\r\n index: true,\r\n },\r\n\r\n redirectUris: {\r\n type: [String],\r\n default: [],\r\n },\r\n\r\n publicClient: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n\r\n // Optional: if you want confidential clients\r\n secret: {\r\n type: String,\r\n required: function (this: IClient) {\r\n return !this.publicClient;\r\n },\r\n },\r\n },\r\n {\r\n timestamps: true,\r\n },\r\n);\r\n\r\nexport const ClientModel: Model<IClient> =\r\n mongoose.models.Client || mongoose.model<IClient>('Client', ClientSchema);\r\n","import jwt from 'jsonwebtoken';\nimport nodemailer from 'nodemailer';\nimport { config } from '../config/index.js';\n\nexport class EmailService {\n private transporter;\n private MAX_EMAILS = 5;\n private WINDOW_MINUTES = 15;\n private BLOCK_HOURS = 1;\n constructor() {\n this.transporter = nodemailer.createTransport({\n host: process.env.EMAIL_HOST || 'smtp.postmarkapp.com',\n port: process.env.EMAIL_PORT ? Number(process.env.EMAIL_PORT) : 587,\n secure: (process.env.EMAIL_SECURE || 'false') === 'true',\n auth: { user: process.env.EMAIL_USER!, pass: process.env.EMAIL_PASSWORD! },\n });\n }\n\n sign(payload: any, ttlSec = 60 * 60 * 24) {\n return jwt.sign(payload, process.env.EMAIL_JWT_SECRET!, { expiresIn: ttlSec });\n }\n\n verify<T = any>(token: string): T {\n return jwt.verify(token, process.env.EMAIL_JWT_SECRET!) as T;\n }\n\n async send(to: string, subject: string, html: string) {\n await this.transporter.sendMail({\n from: process.env.EMAIL_FROM!,\n to,\n subject,\n html,\n });\n }\n\n canSend(lastEmailSent: Date[]) {\n const now = Date.now();\n const windowStart = now - this.WINDOW_MINUTES * 60 * 1000;\n const emailsInWindow = (lastEmailSent || [])\n .map((d) => new Date(d))\n .filter((d) => d.getTime() >= windowStart);\n if (emailsInWindow.length >= this.MAX_EMAILS)\n return {\n ok: false,\n reason: 'RATE_LIMIT',\n waitMs: this.BLOCK_HOURS * 60 * 60 * 1000,\n };\n return { ok: true };\n }\n}\n","import { config } from '../config/index.js';\n\nexport function cookieOpts(isRefresh = false) {\n const maxAge = isRefresh\n ? config.cookies.refreshTtlMs\n : config.cookies.accessTtlMs;\n\n const secure =\n process.env.NODE_ENV === 'production'\n ? (process.env.COOKIE_SECURE ?? true)\n : false;\n\n return {\n httpOnly: true,\n secure,\n sameSite: 'none' as const,\n domain: process.env.COOKIE_DOMAIN!,\n maxAge,\n };\n}\n\nexport function clearOpts() {\n const secure =\n process.env.NODE_ENV === 'production'\n ? (process.env.COOKIE_SECURE ?? true)\n : false;\n\n return {\n domain: process.env.COOKIE_DOMAIN!,\n sameSite: 'none' as const,\n secure,\n };\n}\n","import express, { Router, type Router as ExpressRouter } from 'express';\nimport { AuthAdminService } from '../services/auth-admin.service.js';\nimport { requireAuth } from '../middlewares/auth.middleware.js';\n\nexport function createDashboardRouter(options: any): ExpressRouter {\n const r = Router();\n const kc = new AuthAdminService();\n r.use(express.json());\n\n r.post('/', requireAuth(), async (req, res, next) => {\n try {\n const { slug, isPublic, authFlow, orgDomain } = req.body || {};\n const redirectUris = [`https://${slug}.${orgDomain}/*`];\n const created = await kc.createClient(slug, redirectUris, !!isPublic);\n if (authFlow || isPublic != null) {\n await kc.updateClient(created.id, {\n authenticationFlowBindingOverrides: authFlow\n ? { browser: authFlow }\n : undefined,\n registrationAllowed: !!isPublic,\n });\n }\n res.json({ clientId: created.clientId });\n } catch (e) {\n next(e);\n }\n });\n\n return r;\n}\n","import { Router, type Router as ExpressRouter } from 'express';\n\nexport function createEmailRouter(options: any): ExpressRouter {\n const r = Router();\n\n r.get('/verify', (req, res) =>\n res.json({ ok: true, token: req.query.token }),\n );\n\n return r;\n}\n","import { Router, type Router as ExpressRouter } from 'express';\nimport { requireAuth } from '../middlewares/auth.middleware.js';\nimport { ProjectsService } from '../services/projects.service.js';\n\nexport function createProjectsRouter(options: any): ExpressRouter {\n const r = Router();\n const svc = new ProjectsService();\n\n r.post('/create', requireAuth(), async (req, res) => {\n const { org_id, name, description } = req.body || {};\n const p = await svc.create(org_id, name, description);\n res.json(p);\n });\n\n r.get('/:org_id', requireAuth(), async (req, res) => {\n res.json(await svc.list(req.params.org_id));\n });\n\n r.get('/:org_id/:id', requireAuth(), async (req, res) => {\n res.json(await svc.get(req.params.org_id, req.params.id));\n });\n\n r.put('/:org_id/:id', requireAuth(), async (req, res) => {\n res.json(\n await svc.update(req.params.org_id, req.params.id, req.body || {}),\n );\n });\n\n r.delete('/:org_id/:id', requireAuth(), async (req, res) => {\n res.json(await svc.remove(req.params.org_id, req.params.id));\n });\n\n return r;\n}\n","import { randomUUID } from 'crypto';\nimport { ModuleConnection } from '../models/moduleConnection.model.js';\nimport { Project } from '../models/project.model.js';\n\nexport class ProjectsService {\n async create(org_id: string, name: string, description?: string) {\n const _id = randomUUID();\n const secret = randomUUID();\n const p = await Project.create({ _id, org_id, name, description, secret });\n await ModuleConnection.create({\n projectId: _id,\n modules: { data: [], integration: [], storage: [] },\n });\n return p.toObject();\n }\n\n async list(org_id: string) {\n return Project.find({ org_id }).lean();\n }\n\n async get(org_id: string, id: string) {\n return Project.findOne({ org_id, _id: id }).lean();\n }\n\n async update(org_id: string, id: string, patch: any) {\n return Project.findOneAndUpdate(\n { org_id, _id: id },\n { $set: patch },\n { new: true },\n ).lean();\n }\n\n async remove(org_id: string, id: string) {\n await Project.deleteOne({ org_id, _id: id });\n await ModuleConnection.deleteMany({ projectId: id });\n return { ok: true };\n }\n}\n","import mongoose from 'mongoose';\n\nconst ModuleItemSchema = new mongoose.Schema(\n { id: { type: String, required: true } },\n { _id: false },\n);\n\nconst ModuleConnectionSchema = new mongoose.Schema(\n {\n projectId: { type: String, required: true, index: true },\n modules: {\n data: { type: [ModuleItemSchema], default: [] },\n integration: { type: [ModuleItemSchema], default: [] },\n storage: { type: [ModuleItemSchema], default: [] },\n },\n },\n { timestamps: true, collection: 'module_connection' },\n);\n\nexport const ModuleConnection = mongoose.model(\n 'ModuleConnection',\n ModuleConnectionSchema,\n);\n","import mongoose from 'mongoose';\n\nconst ProjectSchema = new mongoose.Schema(\n {\n _id: { type: String, required: true },\n org_id: { type: String, required: true, index: true },\n name: { type: String, required: true },\n description: { type: String },\n secret: { type: String, required: true },\n },\n { timestamps: true, collection: 'projects' },\n);\n\nexport const Project = mongoose.model('Project', ProjectSchema);\n","import type { AuthUser } from 'aaspai-types';\nimport bcrypt from 'bcryptjs';\nimport { randomUUID } from 'crypto';\nimport express, { Request, Response, Router } from 'express';\nimport { requireAuth } from '../../middlewares/auth.middleware.js';\nimport { requireRole } from '../../middlewares/requireRole.js';\nimport { PermissionsModel } from '../../models/permissions.model';\nimport { RolePermissionModel } from '../../models/rolePermission.model';\nimport { OrgUser } from '../../models/user.model.js';\n\ninterface AuthenticatedRequest extends Request {\n user?: AuthUser;\n}\n\nfunction resolveOrgId(req: AuthenticatedRequest): string | null {\n const user = req.user || {};\n const fromUser = (user.orgId as string) || (user.org_id as string) || null;\n\n const fromQuery = (req.query.orgId as string) || null;\n const fromBody = (req.body && (req.body.orgId as string)) || null;\n\n return fromQuery || fromBody || fromUser;\n}\n\nfunction resolveProjectId(req: AuthenticatedRequest): string | null {\n const user = req.user || {};\n const fromUser = (user.projectId as string) || null;\n\n const fromQuery = (req.query.projectId as string) || null;\n const fromBody = (req.body && (req.body.projectId as string)) || null;\n\n return fromQuery || fromBody || fromUser;\n}\n\nexport function createAdminRouter(_options: any = {}): Router {\n const r = Router();\n\n r.use(express.json());\n r.use(express.urlencoded({ extended: true }));\n\n // All routes require platform_admin (for now).\n const adminGuards = [requireAuth(), requireRole('platform_admin')];\n\n r.post(\n '/users',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n const {\n firstName,\n lastName,\n email: emailAddress,\n password,\n emailVerified = false,\n roles = [],\n } = req.body || {};\n\n const projectId = resolveProjectId(req);\n\n try {\n const hashedPassword = password\n ? await bcrypt.hash(password, 10)\n : undefined;\n\n const user = await OrgUser.create({\n id: randomUUID(),\n email: emailAddress,\n orgId: process.env.ORG_ID!,\n firstName,\n lastName,\n projectId,\n emailVerified,\n metadata: [],\n passwordHash: hashedPassword,\n roles,\n });\n\n return res.json({\n id: user.id,\n email: user.email,\n message: 'Verification email sent. Please check your inbox.',\n });\n } catch (err: any) {\n console.error('Create user error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.delete(\n '/users',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const userId = (req?.body?.id || req?.query?.id) as string | undefined;\n\n if (!userId) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'UserId is required (send in body.id or ?id=...)',\n });\n }\n\n const deleted = await OrgUser.findOneAndDelete({ id: userId }).exec();\n\n if (!deleted) {\n return res.status(404).json({\n error: 'NOT_FOUND',\n message: 'User not found or already deleted',\n });\n }\n\n return res.status(200).json({\n ok: true,\n message: 'User deleted successfully',\n deletedUser: {\n id: deleted.id,\n firstName: deleted.firstName,\n email: deleted.email,\n orgId: deleted.orgId,\n },\n });\n } catch (err: any) {\n console.error('Delete user error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.put(\n '/users/:id',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n const userId = req.params.id;\n\n const {\n firstName,\n lastName,\n email: emailAddress,\n password,\n emailVerified,\n roles,\n } = req.body || {};\n\n try {\n const existingUser = await OrgUser.findOne({\n id: userId,\n orgId: process.env.ORG_ID!,\n });\n\n if (!existingUser) {\n return res.status(404).json({ error: 'USER_NOT_FOUND' });\n }\n\n // Only update allowed fields\n if (firstName !== undefined) existingUser.firstName = firstName;\n if (lastName !== undefined) existingUser.lastName = lastName;\n if (emailAddress !== undefined) existingUser.email = emailAddress;\n if (emailVerified !== undefined)\n existingUser.emailVerified = emailVerified;\n if (roles !== undefined) existingUser.roles = roles;\n\n // Password (if provided)\n if (password) {\n existingUser.passwordHash = await bcrypt.hash(password, 10);\n }\n\n // DO NOT UPDATE projectId — keep original value forever\n // existingUser.projectId stays as-is\n\n await existingUser.save();\n\n return res.json({\n id: existingUser.id,\n email: existingUser.email,\n message: 'User updated successfully.',\n });\n } catch (err: any) {\n console.error('Update user error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * GET /permissions\n * List API configs (permissions) for an org (or platform/global when orgId is absent).\n */\n r.get(\n '/permissions',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n\n const filter: any = {};\n if (orgId !== null) {\n filter.orgId = orgId;\n } else {\n filter.orgId = null;\n }\n\n const items = await PermissionsModel.find(filter).lean().exec();\n return res.json(items);\n } catch (err) {\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * POST /permissions\n * Create a new API config (permission).\n * Body:\n * {\n * orgId?: string,\n * key: string,\n * method: string,\n * path: string,\n * module?: string,\n * description?: string,\n * isInternal?: boolean\n * }\n *\n * Also auto-assigns this permission to platform_admin for that org.\n */\n r.post(\n '/permissions',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n\n const {\n key,\n type,\n apiId,\n description,\n isInternal = false,\n } = req.body || {};\n\n if (!key || !type) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'permission key, and permission type are required',\n });\n }\n\n const id = randomUUID();\n\n const permission = await PermissionsModel.create({\n id,\n orgId: orgId ?? null,\n key,\n type,\n apiId,\n description,\n isInternal: !!isInternal,\n });\n\n // Auto-assign to platform_admin role for this org\n await RolePermissionModel.findOneAndUpdate(\n { orgId: orgId ?? null, role: 'platform_admin' },\n { $addToSet: { permissions: key } },\n { upsert: true, new: true },\n ).exec();\n\n return res.status(201).json(permission);\n } catch (err: any) {\n if (err && err.code === 11000) {\n return res.status(409).json({\n error: 'DUPLICATE_PERMISSION',\n message: 'Permission key already exists for this org',\n });\n }\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.put(\n '/permissions/:id',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n const permissionId = req.params.id;\n\n const { key, type, apiId, description, isInternal } = req.body || {};\n // Fetch existing permission\n const existing = await PermissionsModel.findOne({\n id: permissionId,\n orgId: orgId ?? null,\n });\n\n if (!existing) {\n return res.status(404).json({\n error: 'NOT_FOUND',\n message: 'Permission does not exist',\n });\n }\n\n const oldKey = existing.key;\n\n // Apply updates\n if (key !== undefined) existing.key = key;\n if (type !== undefined) existing.type = type;\n if (apiId !== undefined) existing.apiId = apiId;\n if (description !== undefined) existing.description = description;\n if (isInternal !== undefined) existing.isInternal = !!isInternal;\n\n await existing.save();\n\n if (oldKey !== key) {\n // 1. Remove old key\n await RolePermissionModel.updateMany(\n {\n orgId: orgId ?? null,\n permissions: oldKey,\n },\n {\n $pull: { permissions: oldKey },\n },\n );\n\n // 2. Add new key\n await RolePermissionModel.updateMany(\n {\n orgId: orgId ?? null,\n },\n {\n $addToSet: { permissions: key },\n },\n );\n }\n\n return res.json(existing);\n } catch (err: any) {\n if (err && err.code === 11000) {\n return res.status(409).json({\n error: 'DUPLICATE_PERMISSION',\n message: 'Permission key already exists for this org',\n });\n }\n\n console.error('Update permission error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.delete(\n '/permissions',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const permissionId = (req?.body?.id || req?.query?.id) as\n | string\n | undefined;\n\n if (!permissionId) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'Permission id is required (send in body.id or ?id=...)',\n });\n }\n\n // Fetch permission before deletion → we need key + orgId\n const existing = await PermissionsModel.findOne({ id: permissionId });\n if (!existing) {\n return res.status(404).json({\n error: 'NOT_FOUND',\n message: 'Permission not found or already deleted',\n });\n }\n\n const { key, orgId } = existing;\n\n // Delete permission\n await PermissionsModel.deleteOne({ id: permissionId });\n\n // Remove permission key from all roles in THE SAME org\n await RolePermissionModel.updateMany(\n { orgId: orgId ?? null },\n { $pull: { permissions: key } },\n );\n\n return res.status(200).json({\n ok: true,\n message: 'Permission deleted successfully',\n deletedPermission: {\n id: existing.id,\n key: existing.key,\n type: existing.type,\n apiId: existing.apiId,\n description: existing.description,\n isInternal: existing.isInternal,\n orgId: existing.orgId,\n },\n });\n } catch (err: any) {\n console.error('Delete permission error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * GET /roles\n * List role-permissions for org.\n * Query: ?orgId=...\n */\n r.get(\n '/roles',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n\n const filter: any = {};\n if (orgId !== null) {\n filter.orgId = orgId;\n } else {\n filter.orgId = null;\n }\n\n const roles = await RolePermissionModel.find(filter).lean().exec();\n return res.json(roles);\n } catch (err) {\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * POST /roles\n * Create or replace a role's permission set.\n *\n * Body:\n * {\n * orgId?: string,\n * role: string,\n * permissions: string[]\n * }\n */\n r.post(\n '/roles',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n const { role, permissions } = req.body || {};\n\n if (!role || !Array.isArray(permissions)) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'role and permissions[] are required',\n });\n }\n\n const id = randomUUID();\n\n const doc = await RolePermissionModel.findOneAndUpdate(\n { orgId: orgId ?? null, role },\n { $set: { permissions } },\n { upsert: true, new: true },\n ).exec();\n\n return res.status(200).json(doc);\n } catch (err) {\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.put(\n '/roles/:id',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n const roleId = req.params.id;\n\n const { role: newRoleName, permissions } = req.body || {};\n\n if (!newRoleName || !Array.isArray(permissions)) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'role and permissions are required',\n });\n }\n\n // 1. Find the existing role\n const existing = await RolePermissionModel.findById(roleId);\n\n if (!existing) {\n return res.status(404).json({\n error: 'ROLE_NOT_FOUND',\n message: 'Role does not exist',\n });\n }\n\n const oldRoleName = existing.role;\n\n // 2. Update the role document\n existing.role = newRoleName;\n existing.permissions = permissions;\n await existing.save();\n\n if (oldRoleName !== newRoleName) {\n // Step 1 — remove old role from all users\n await OrgUser.updateMany(\n {\n orgId: orgId ?? null,\n roles: oldRoleName,\n },\n {\n $pull: { roles: oldRoleName },\n },\n );\n\n // Step 2 — add new role to users that previously had the old role\n await OrgUser.updateMany(\n {\n orgId: orgId ?? null,\n roles: { $ne: newRoleName }, // avoid duplicates\n },\n {\n $addToSet: { roles: newRoleName },\n },\n );\n }\n\n return res.status(200).json(existing);\n } catch (err) {\n console.error('Update role error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * DELETE /roles\n * Delete a role completely (by MongoDB _id)\n *\n * Body:\n * {\n * \"id\": \"507f1f77bcf86cd799439011\" // MongoDB _id of the RolePermission document\n * }\n *\n * Query alternative (optional):\n * ?id=507f1f77bcf86cd799439011\n */\n r.delete(\n '/roles',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const roleId = (req?.body?.id || req?.query?.id) as string | undefined;\n\n if (!roleId) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'Role _id is required (send in body.id or ?id=...)',\n });\n }\n\n // Optional: validate it's a valid ObjectId\n if (!/^[0-9a-fA-F]{24}$/.test(roleId)) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'Invalid role _id format',\n });\n }\n\n const deleted =\n await RolePermissionModel.findByIdAndDelete(roleId).exec();\n\n if (!deleted) {\n return res.status(404).json({\n error: 'NOT_FOUND',\n message: 'Role not found or already deleted',\n });\n }\n\n return res.status(200).json({\n ok: true,\n message: 'Role deleted successfully',\n deletedRole: {\n _id: deleted._id,\n role: deleted.role,\n orgId: deleted.orgId,\n },\n });\n } catch (err: any) {\n console.error('Delete role error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n return r;\n}\n","import type { AuthXSession } from 'aaspai-types';\r\n\r\n/**\r\n * Check if a session has a specific role\r\n */\r\nexport function hasRole(\r\n session: AuthXSession | null | undefined,\r\n role: string,\r\n): boolean {\r\n if (!session || !session.roles) return false;\r\n return session.roles.includes(role);\r\n}\r\n\r\n/**\r\n * Check if a session has any of the specified roles\r\n */\r\nexport function hasAnyRole(\r\n session: AuthXSession | null | undefined,\r\n roles: string[],\r\n): boolean {\r\n if (\r\n !session ||\r\n !session.roles ||\r\n !Array.isArray(roles) ||\r\n roles.length === 0\r\n ) {\r\n return false;\r\n }\r\n return roles.some((role) => session.roles.includes(role));\r\n}\r\n\r\n/**\r\n * Check if a session has all of the specified roles\r\n */\r\nexport function hasAllRoles(\r\n session: AuthXSession | null | undefined,\r\n roles: string[],\r\n): boolean {\r\n if (\r\n !session ||\r\n !session.roles ||\r\n !Array.isArray(roles) ||\r\n roles.length === 0\r\n ) {\r\n return false;\r\n }\r\n return roles.every((role) => session.roles.includes(role));\r\n}\r\n\r\n/**\r\n * Check if a session has a specific permission\r\n */\r\nexport function hasPermission(\r\n session: AuthXSession | null | undefined,\r\n permission: string,\r\n): boolean {\r\n if (!session || !session.permissions) return false;\r\n return session.permissions.includes(permission);\r\n}\r\n\r\n/**\r\n * Check if a session has any of the specified permissions\r\n */\r\nexport function hasAnyPermission(\r\n session: AuthXSession | null | undefined,\r\n permissions: string[],\r\n): boolean {\r\n if (\r\n !session ||\r\n !session.permissions ||\r\n !Array.isArray(permissions) ||\r\n permissions.length === 0\r\n ) {\r\n return false;\r\n }\r\n return permissions.some((perm) => session.permissions.includes(perm));\r\n}\r\n\r\n/**\r\n * Check if a session has all of the specified permissions\r\n */\r\nexport function hasAllPermissions(\r\n session: AuthXSession | null | undefined,\r\n permissions: string[],\r\n): boolean {\r\n if (\r\n !session ||\r\n !session.permissions ||\r\n !Array.isArray(permissions) ||\r\n permissions.length === 0\r\n ) {\r\n return false;\r\n }\r\n return permissions.every((perm) => session.permissions.includes(perm));\r\n}\r\n","import type { AuthXSession } from 'aaspai-types';\r\nimport type { NextFunction, Request, Response } from 'express';\r\nimport { hasAnyRole } from '../core/utils.js';\r\n\r\n/**\r\n * Express middleware to require one or more roles\r\n * @param roles - Array of role names (user must have at least one)\r\n */\r\nexport function requireRole(...roles: string[]) {\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n const user = (req as any).user as AuthXSession | undefined;\r\n\r\n if (!user) {\r\n return res.status(401).json({ error: 'Unauthorized' });\r\n }\r\n\r\n if (!roles || roles.length === 0) {\r\n return next();\r\n }\r\n\r\n if (!hasAnyRole(user, roles)) {\r\n return res.status(403).json({\r\n error: `Requires one of roles: ${roles.join(', ')}`,\r\n required: roles,\r\n userRoles: user.roles,\r\n });\r\n }\r\n\r\n next();\r\n };\r\n}\r\n","import mongoose, { Document, Schema } from 'mongoose';\r\n\r\nexport interface PermissionsDocument extends Document {\r\n id: string; // stable UUID\r\n orgId?: string | null; // null => platform/global\r\n key: string; // permission key, e.g. \"users.read\"\r\n type: string; // \"GET\", \"POST\", ...\r\n apiId?: string; // \"/api/users\"\r\n description?: string;\r\n isInternal: boolean; // internal vs external\r\n createdAt: Date;\r\n updatedAt: Date;\r\n}\r\n\r\nconst PermissionsSchema = new Schema<PermissionsDocument>(\r\n {\r\n id: { type: String, required: true, index: true },\r\n orgId: { type: String, default: null, index: true },\r\n key: { type: String, required: true },\r\n type: { type: String, required: true },\r\n apiId: { type: String, required: false },\r\n description: { type: String },\r\n isInternal: { type: Boolean, default: false },\r\n },\r\n {\r\n timestamps: true,\r\n },\r\n);\r\n\r\n// One permission key per org\r\nPermissionsSchema.index({ orgId: 1, key: 1 }, { unique: true });\r\n\r\nexport const PermissionsModel = mongoose.model<PermissionsDocument>(\r\n 'Permissions',\r\n PermissionsSchema,\r\n 'permissions',\r\n);\r\n","import type { INestApplication } from '@nestjs/common';\nimport { Db } from 'mongodb';\nimport {\n createAdminRouter,\n createAuthRouter,\n createDashboardRouter,\n createEmailRouter,\n createProjectsRouter,\n} from '../express';\nimport type { AuthRouterOptions } from 'aaspai-types';\n\nexport interface NestAuthxOptions {\n routerOptions?: AuthRouterOptions;\n adminDb?: Db;\n adminBasePath?: string;\n authBasePath?: string;\n dashboardBasePath?: string;\n dnsBasePath?: string;\n emailBasePath?: string;\n uploadBasePath?: string;\n projectsBasePath?: string;\n}\n\nexport const nest = {\n mountAuthRouter(\n app: INestApplication,\n options: NestAuthxOptions,\n ): {\n authRouter: any;\n dashboardRouter?: any;\n dnsRouter?: any;\n emailRouter?: any;\n uploadRouter?: any;\n projectsRouter?: any;\n adminRouter?: any;\n } {\n const httpAdapter = app.getHttpAdapter().getInstance();\n\n const authRouter = createAuthRouter(options.routerOptions || {});\n const authPath = options.authBasePath || '/auth';\n httpAdapter.use(authPath, authRouter);\n\n const adminRouter = createAdminRouter(options);\n const adminPath = options.adminBasePath || '/admin';\n httpAdapter.use(adminPath, adminRouter);\n\n const dashboardRouter = createDashboardRouter(options);\n const dashboardPath = options.dashboardBasePath || '/dashboards';\n httpAdapter.use(dashboardPath, dashboardRouter);\n\n const emailRouter = createEmailRouter(options);\n const emailPath = options.emailBasePath || '/email';\n httpAdapter.use(emailPath, emailRouter);\n\n const projectsRouter = createProjectsRouter(options);\n const projectsPath = options.projectsBasePath || '/projects';\n httpAdapter.use(projectsPath, projectsRouter);\n\n return {\n authRouter,\n dashboardRouter,\n emailRouter,\n projectsRouter,\n adminRouter,\n };\n },\n};\n","// src/middlewares/permission.middleware.ts\r\nimport type { AuthXUser } from 'aaspai-types';\r\nimport { NextFunction, Request, Response } from 'express';\r\nimport { RolePermissionModel } from '../models/rolePermission.model';\r\n\r\ninterface AuthenticatedRequest extends Request {\r\n user?: AuthXUser;\r\n}\r\n\r\nexport function requirePermission(permissionKey: string) {\r\n return async (\r\n req: AuthenticatedRequest,\r\n res: Response,\r\n next: NextFunction,\r\n ) => {\r\n try {\r\n console.log('INSIDE PERMISSION MIDDLEWARE', permissionKey);\r\n const user = req.user;\r\n\r\n if (!user) {\r\n return res.status(401).json({ error: 'Unauthorized' });\r\n }\r\n\r\n const roles = Array.isArray(user.roles) ? user.roles : [];\r\n\r\n if (!roles.length) {\r\n return res.status(403).json({ error: 'Forbidden', reason: 'NO_ROLES' });\r\n }\r\n\r\n // Global superuser shortcut\r\n if (roles.includes('platform_admin')) {\r\n return next();\r\n }\r\n\r\n // Try to determine org context (you can refine this later)\r\n const orgId =\r\n (user.orgId as string) ||\r\n (user.org_id as string) ||\r\n (user.projectId as string) ||\r\n null;\r\n\r\n const rolePermissions = await RolePermissionModel.find({\r\n orgId,\r\n role: { $in: roles },\r\n })\r\n .lean()\r\n .exec();\r\n\r\n const allowed = new Set<string>();\r\n\r\n for (const rp of rolePermissions) {\r\n if (Array.isArray(rp.permissions)) {\r\n for (const p of rp.permissions) {\r\n allowed.add(p);\r\n }\r\n }\r\n }\r\n\r\n if (!allowed.has(permissionKey)) {\r\n return res.status(403).json({\r\n error: 'Forbidden',\r\n reason: 'MISSING_PERMISSION',\r\n permission: permissionKey,\r\n });\r\n }\r\n\r\n return next();\r\n } catch (err) {\r\n return next(err);\r\n }\r\n };\r\n}\r\n","import type { NextFunction, Request, Response } from 'express';\r\nimport { hasPermission } from '../core/utils.js';\r\nimport type { AuthXSession } from 'aaspai-types';\r\n\r\n/**\r\n * Express middleware to require a specific permission\r\n * @param permission - Permission string (e.g., 'projects.create')\r\n */\r\nexport function requirePermission(permission: string) {\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n const user = (req as any).user as AuthXSession | undefined;\r\n\r\n if (!user) {\r\n return res.status(401).json({ error: 'Unauthorized' });\r\n }\r\n\r\n if (!permission) {\r\n return next();\r\n }\r\n\r\n if (!hasPermission(user, permission)) {\r\n return res.status(403).json({\r\n error: 'Forbidden',\r\n reason: 'MISSING_PERMISSION',\r\n permission,\r\n userPermissions: user.permissions,\r\n });\r\n }\r\n\r\n next();\r\n };\r\n}\r\n\r\n","import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';\nimport { randomUUID } from 'crypto';\nimport { config } from '../config/index.js';\n\nexport class UploadsService {\n private s3: S3Client;\n\n constructor() {\n this.s3 = new S3Client({\n region: process.env.AWS_REGION!,\n credentials: {\n accessKeyId: process.env.AWS_ACCESS_KEY_ID!,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,\n },\n });\n }\n\n async uploadPublicImage(buffer: Buffer, mimetype: string, ext: string) {\n const key = `${randomUUID()}.${ext}`;\n await this.s3.send(\n new PutObjectCommand({\n Bucket: process.env.AWS_S3_BUCKET!,\n Key: key,\n Body: buffer,\n ACL: 'public-read',\n ContentType: mimetype,\n }),\n );\n return `https://${process.env.AWS_S3_BUCKET!}.s3.${process.env.AWS_REGION!}.amazonaws.com/${key}`;\n }\n}\n","import {\r\n ExecutionContext,\r\n ForbiddenException,\r\n Injectable,\r\n UnauthorizedException,\r\n} from '@nestjs/common';\r\nimport { Reflector } from '@nestjs/core';\r\nimport { AuthGuard } from '@nestjs/passport';\r\nimport type { AuthXSession } from 'aaspai-types';\r\nimport { hasAnyPermission, hasAnyRole } from '../core/utils.js';\r\nimport { PERMISSIONS_KEY } from './decorators/permissions.decorator.js';\r\nimport { ROLES_KEY } from './decorators/roles.decorator.js';\r\n\r\n/**\r\n * AuthX Guard for NestJS\r\n * Extends Passport's AuthGuard to authenticate requests using AuthXStrategy,\r\n * then validates role/permission requirements\r\n */\r\n@Injectable()\r\nexport class AuthXGuard extends AuthGuard('authx') {\r\n private readonly reflector = new Reflector();\r\n\r\n constructor() {\r\n super();\r\n }\r\n\r\n /**\r\n * Override handleRequest to convert Passport errors to NestJS exceptions\r\n * This prevents the \"Right-hand side of 'instanceof' is not an object\" error\r\n */\r\n handleRequest(err: any, user: any, info: any, context: any): any {\r\n // If there's an error or no user, throw UnauthorizedException\r\n if (err || !user) {\r\n const message =\r\n err?.message || info?.message || 'Authentication required';\r\n throw new UnauthorizedException(message);\r\n }\r\n return user;\r\n }\r\n\r\n async canActivate(context: ExecutionContext): Promise<boolean> {\r\n try {\r\n // First, trigger Passport authentication (this will set request.user via AuthXStrategy)\r\n // Wrap in try-catch to handle any errors from Passport\r\n let authenticated: boolean;\r\n try {\r\n authenticated = (await super.canActivate(context)) as boolean;\r\n } catch (passportError: any) {\r\n // Convert any Passport errors to UnauthorizedException\r\n const message = passportError?.message || 'Authentication required';\r\n throw new UnauthorizedException(message);\r\n }\r\n\r\n if (!authenticated) {\r\n throw new UnauthorizedException('Authentication required');\r\n }\r\n\r\n const request = context.switchToHttp().getRequest();\r\n const user = (request as any).user as AuthXSession | undefined;\r\n\r\n // Check if user is authenticated (should be set by Passport at this point)\r\n if (!user) {\r\n throw new UnauthorizedException('Authentication required');\r\n }\r\n\r\n // Get required roles from metadata\r\n const requiredRoles = this.reflector.getAllAndOverride<string[]>(\r\n ROLES_KEY,\r\n [context.getHandler(), context.getClass()],\r\n );\r\n \r\n // Get required permissions from metadata\r\n const requiredPermissions = this.reflector.getAllAndOverride<string[]>(\r\n PERMISSIONS_KEY,\r\n [context.getHandler(), context.getClass()],\r\n );\r\n\r\n // Check roles if specified\r\n if (requiredRoles && requiredRoles.length > 0) {\r\n if (!hasAnyRole(user, requiredRoles)) {\r\n throw new ForbiddenException(\r\n `Requires one of roles: ${requiredRoles.join(', ')}`,\r\n );\r\n }\r\n }\r\n\r\n // Check permissions if specified\r\n if (requiredPermissions && requiredPermissions.length > 0) {\r\n if (!hasAnyPermission(user, requiredPermissions)) {\r\n throw new ForbiddenException(\r\n `Requires one of permissions: ${requiredPermissions.join(', ')}`,\r\n );\r\n }\r\n }\r\n\r\n return true;\r\n } catch (error) {\r\n // If it's already a NestJS exception, rethrow it\r\n if (\r\n error instanceof UnauthorizedException ||\r\n error instanceof ForbiddenException\r\n ) {\r\n throw error;\r\n }\r\n // Otherwise, wrap it in UnauthorizedException\r\n const errorMessage =\r\n error instanceof Error ? error.message : String(error);\r\n throw new UnauthorizedException(errorMessage || 'Authentication failed');\r\n }\r\n }\r\n}\r\n","import { SetMetadata } from '@nestjs/common';\r\n\r\nexport const PERMISSIONS_KEY = 'permissions';\r\n\r\n/**\r\n * Decorator to specify required permissions for a route handler or controller\r\n * @param permissions - Array of permission strings (user must have at least one)\r\n */\r\nexport const Permissions = (...permissions: string[]) =>\r\n SetMetadata(PERMISSIONS_KEY, permissions);\r\n\r\n","import { SetMetadata } from '@nestjs/common';\r\n\r\nexport const ROLES_KEY = 'roles';\r\n\r\n/**\r\n * Decorator to specify required roles for a route handler or controller\r\n * @param roles - Array of role names (user must have at least one)\r\n */\r\nexport const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);\r\n\r\n","import { createParamDecorator, ExecutionContext } from '@nestjs/common';\r\nimport type { AuthXSession } from 'aaspai-types';\r\n\r\n/**\r\n * Decorator to inject the AuthXSession into a route handler parameter\r\n * Usage: @AuthXSessionDecorator() session: AuthXSession\r\n */\r\nexport const AuthXSessionDecorator = createParamDecorator(\r\n (data: unknown, ctx: ExecutionContext): AuthXSession | null => {\r\n const request = ctx.switchToHttp().getRequest();\r\n return (request as any).user || null;\r\n },\r\n);\r\n","import type { Request } from 'express';\r\nimport { Strategy } from 'passport';\r\nimport { OrgUser } from '../models/user.model.js';\r\nimport { buildSession } from '../core/session.js';\r\nimport { extractToken } from '../utils/extract.js';\r\nimport { verifyJwt } from '../utils/jwt.js';\r\n\r\n/**\r\n * AuthX Passport Strategy\r\n * Custom Passport strategy that validates JWT tokens using JWKS\r\n * and builds AuthXSession\r\n */\r\nexport class AuthXStrategy extends Strategy {\r\n name = 'authx';\r\n\r\n async authenticate(req: Request) {\r\n try {\r\n const apiKey = req.headers['x-api-key'] as string | undefined;\r\n const userId = req.headers['x-user-id'] as string | undefined;\r\n\r\n if (apiKey) {\r\n if (apiKey !== process.env.SERVER_API_KEY) {\r\n return this.fail({ message: 'Invalid API key' }, 401);\r\n }\r\n if (!userId) {\r\n return this.fail({ message: 'User Id is required' }, 401);\r\n }\r\n\r\n const user = await OrgUser.findOne({\r\n id: userId,\r\n orgId: process.env.ORG_ID || null,\r\n });\r\n\r\n if (!user) {\r\n return this.fail({ message: 'User not found' }, 401);\r\n }\r\n\r\n // Build a synthetic session\r\n const session = buildSession(user);\r\n\r\n // Attach to request\r\n (req as any).user = session;\r\n\r\n return this.success(session);\r\n } else {\r\n \r\n // Extract token from request using existing utility\r\n const token = extractToken(req);\r\n\r\n if (!token) {\r\n return this.fail({ message: 'Missing token' }, 401);\r\n }\r\n\r\n // Verify JWT asynchronously\r\n verifyJwt(token)\r\n .then((claims) => {\r\n // Build canonical session\r\n const session = buildSession(claims);\r\n\r\n // Attach to request\r\n (req as any).user = session;\r\n\r\n // Success\r\n return this.success(session);\r\n })\r\n .catch((error: any) => {\r\n // Verification failed\r\n return this.fail(\r\n { message: error?.message || 'Unauthorized' },\r\n 401,\r\n );\r\n });\r\n }\r\n } catch (error: any) {\r\n return this.fail({ message: error?.message || 'Unauthorized' }, 401);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create AuthXStrategy instance\r\n */\r\nexport function createAuthXStrategy() {\r\n return new AuthXStrategy();\r\n}\r\n","import type { AuthXSession } from 'aaspai-types';\r\nimport { cookies } from 'next/headers';\r\nimport { buildSession } from '../../core/session.js';\r\nimport { verifyJwt } from '../../utils/jwt.js';\r\n\r\n/**\r\n * Get the current authenticated session in Next.js App Router\r\n * Reads the access_token cookie (or authorization header) and verifies the JWT\r\n * @returns Session object or null if not authenticated\r\n */\r\nexport async function authx(): Promise<{ session: AuthXSession | null }> {\r\n try {\r\n const cookieStore = await cookies();\r\n\r\n // Try multiple cookie names (matching extractToken behavior)\r\n const token =\r\n cookieStore.get('access_token')?.value ||\r\n cookieStore.get('authorization')?.value ||\r\n cookieStore.get('auth_token')?.value ||\r\n null;\r\n\r\n if (!token) {\r\n return { session: null };\r\n }\r\n\r\n // Verify JWT using the same verification logic as backend\r\n const claims = await verifyJwt(token);\r\n\r\n // Build canonical session\r\n const session = buildSession(claims);\r\n\r\n return { session };\r\n } catch (error) {\r\n // If verification fails, return null session\r\n return { session: null };\r\n }\r\n}\r\n","import type { NextRequest } from 'next/server';\r\nimport { NextResponse } from 'next/server';\r\nimport { authx } from './authx.js';\r\nimport { hasPermission } from '../../core/utils.js';\r\nimport type { AuthXSession } from 'aaspai-types';\r\n\r\n\r\n/**\r\n * Type for Next.js route handler\r\n */\r\nexport type NextRouteHandler = (\r\n req: NextRequest,\r\n context?: any,\r\n) => Promise<NextResponse> | NextResponse;\r\n\r\ntype AuthRouteHandler = (\r\n req: NextRequest,\r\n session: AuthXSession,\r\n context?: any,\r\n) => Promise<NextResponse> | NextResponse;\r\n\r\n/**\r\n * Wrap a Next.js route handler with authentication and optional permission check\r\n * @param permission - Optional permission string to require\r\n * @param handler - The route handler function\r\n * @returns Wrapped handler that checks authentication/permissions\r\n */\r\nexport function withAuthRoute(\r\n permission: string,\r\n handler: AuthRouteHandler,\r\n): NextRouteHandler;\r\n\r\nexport function withAuthRoute(handler: AuthRouteHandler): NextRouteHandler;\r\n\r\nexport function withAuthRoute(\r\n permissionOrHandler: string | AuthRouteHandler,\r\n handler?: AuthRouteHandler,\r\n): NextRouteHandler {\r\n // Handle overloaded signature\r\n let permission: string | undefined;\r\n let routeHandler: AuthRouteHandler;\r\n\r\n if (typeof permissionOrHandler === 'string') {\r\n permission = permissionOrHandler;\r\n routeHandler = handler!;\r\n } else {\r\n permission = undefined;\r\n routeHandler = permissionOrHandler;\r\n }\r\n\r\n return async (req: NextRequest, context?: any) => {\r\n // Get session\r\n const { session } = await authx();\r\n\r\n if (!session) {\r\n return new NextResponse(\r\n JSON.stringify({ error: 'Unauthorized' }),\r\n { status: 401, headers: { 'Content-Type': 'application/json' } },\r\n );\r\n }\r\n\r\n // Check permission if specified\r\n if (permission && !hasPermission(session, permission)) {\r\n return new NextResponse(\r\n JSON.stringify({\r\n error: 'Forbidden',\r\n reason: 'MISSING_PERMISSION',\r\n permission,\r\n }),\r\n { status: 403, headers: { 'Content-Type': 'application/json' } },\r\n );\r\n }\r\n\r\n // Call the handler with session\r\n return routeHandler(req, session, context);\r\n };\r\n}\r\n\r\n","'use client';\r\n\r\nimport type { AuthXSession } from 'aaspai-types';\r\nimport React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';\r\n\r\ninterface AuthXContextValue {\r\n session: AuthXSession | null;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n}\r\n\r\nconst AuthXContext = createContext<AuthXContextValue | undefined>(undefined);\r\n\r\ninterface AuthXProviderProps {\r\n children: ReactNode;\r\n apiUrl?: string;\r\n}\r\n\r\n/**\r\n * AuthX Provider component\r\n * Provides authentication context to the application\r\n * Fetches session from /auth/me endpoint\r\n */\r\nexport function AuthXProvider({ children, apiUrl = '/auth/me' }: AuthXProviderProps) {\r\n const [session, setSession] = useState<AuthXSession | null>(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetchSession = async () => {\r\n try {\r\n setIsLoading(true);\r\n setError(null);\r\n const response = await fetch(apiUrl, {\r\n credentials: 'include', // Include cookies\r\n });\r\n\r\n if (!response.ok) {\r\n if (response.status === 401) {\r\n setSession(null);\r\n return;\r\n }\r\n throw new Error(`Failed to fetch session: ${response.statusText}`);\r\n }\r\n\r\n const data: any = await response.json();\r\n // Assume the API returns a user object that we can convert to session\r\n // If the API already returns AuthXSession format, use it directly\r\n setSession(data.user || data.session || data);\r\n } catch (err) {\r\n setError(err instanceof Error ? err : new Error('Unknown error'));\r\n setSession(null);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n fetchSession();\r\n }, [apiUrl]);\r\n\r\n const value: AuthXContextValue = {\r\n session,\r\n isLoading,\r\n error,\r\n refetch: fetchSession,\r\n };\r\n\r\n return <AuthXContext.Provider value={value}>{children}</AuthXContext.Provider>;\r\n}\r\n\r\n/**\r\n * Hook to access AuthX context\r\n * @throws Error if used outside AuthXProvider\r\n */\r\nexport function useAuthXContext(): AuthXContextValue {\r\n const context = useContext(AuthXContext);\r\n if (context === undefined) {\r\n throw new Error('useAuthX must be used within an AuthXProvider');\r\n }\r\n return context;\r\n}\r\n\r\n","'use client';\r\n\r\nimport { ReactNode } from 'react';\r\nimport { hasPermission } from '../../core/utils.js';\r\nimport { useAuthXContext } from './AuthXProvider.js';\r\n\r\ninterface HasPermissionProps {\r\n permission: string;\r\n children: ReactNode;\r\n fallback?: ReactNode;\r\n}\r\n\r\n/**\r\n * Component that only renders children when user has the specified permission\r\n */\r\nexport function HasPermission({\r\n permission,\r\n children,\r\n fallback = null,\r\n}: HasPermissionProps) {\r\n const { session, isLoading } = useAuthXContext();\r\n\r\n if (isLoading) {\r\n return null;\r\n }\r\n\r\n if (!session) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n const hasPerm = hasPermission(session, permission);\r\n\r\n if (!hasPerm) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n return <>{children}</>;\r\n}\r\n","'use client';\r\n\r\nimport { ReactNode } from 'react';\r\nimport { hasAnyRole } from '../../core/utils.js';\r\nimport { useAuthXContext } from './AuthXProvider.js';\r\n\r\ninterface HasRoleProps {\r\n role: string | string[];\r\n children: ReactNode;\r\n fallback?: ReactNode;\r\n}\r\n\r\n/**\r\n * Component that only renders children when user has the specified role(s)\r\n */\r\nexport function HasRole({ role, children, fallback = null }: HasRoleProps) {\r\n const { session, isLoading } = useAuthXContext();\r\n\r\n if (isLoading) {\r\n return null;\r\n }\r\n\r\n if (!session) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n const roles = Array.isArray(role) ? role : [role];\r\n const hasRole = hasAnyRole(session, roles);\r\n\r\n if (!hasRole) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n return <>{children}</>;\r\n}\r\n","'use client';\r\n\r\nimport { ReactNode } from 'react';\r\nimport { useAuthXContext } from './AuthXProvider.js';\r\n\r\ninterface SignedInProps {\r\n children: ReactNode;\r\n fallback?: ReactNode;\r\n}\r\n\r\n/**\r\n * Component that only renders children when user is signed in\r\n */\r\nexport function SignedIn({ children, fallback = null }: SignedInProps) {\r\n const { session, isLoading } = useAuthXContext();\r\n\r\n if (isLoading) {\r\n return null; // Or a loading spinner\r\n }\r\n\r\n if (!session) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n return <>{children}</>;\r\n}\r\n","'use client';\r\n\r\nimport React, { ReactNode } from 'react';\r\nimport { useAuthXContext } from './AuthXProvider.js';\r\n\r\ninterface SignedOutProps {\r\n children: ReactNode;\r\n fallback?: ReactNode;\r\n}\r\n\r\n/**\r\n * Component that only renders children when user is signed out\r\n */\r\nexport function SignedOut({ children, fallback = null }: SignedOutProps) {\r\n const { session, isLoading } = useAuthXContext();\r\n\r\n if (isLoading) {\r\n return null; // Or a loading spinner\r\n }\r\n\r\n if (session) {\r\n return <>{fallback}</>;\r\n }\r\n\r\n return <>{children}</>;\r\n}\r\n\r\n","'use client';\r\n\r\nimport { useAuthXContext } from './AuthXProvider.js';\r\n\r\n/**\r\n * Hook to access the current authentication session\r\n * @returns Object with session, isLoading, error, and refetch function\r\n */\r\nexport function useAuthX() {\r\n const { session, isLoading, error, refetch } = useAuthXContext();\r\n\r\n return {\r\n session,\r\n isLoading,\r\n error,\r\n refetch,\r\n isSignedIn: !!session,\r\n userId: session?.userId || null,\r\n email: session?.email || null,\r\n roles: session?.roles || [],\r\n permissions: session?.permissions || [],\r\n };\r\n}\r\n\r\n/**\r\n * Hook to check if user has a specific role\r\n */\r\nexport function useHasRole(role: string): boolean {\r\n const { session } = useAuthXContext();\r\n if (!session || !session.roles) return false;\r\n return session.roles.includes(role);\r\n}\r\n\r\n/**\r\n * Hook to check if user has a specific permission\r\n */\r\nexport function useHasPermission(permission: string): boolean {\r\n const { session } = useAuthXContext();\r\n if (!session || !session.permissions) return false;\r\n return session.permissions.includes(permission);\r\n}\r\n"],"mappings":"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","names":["requirePermission","import_jsonwebtoken","mongoose","import_mongoose","mongoose","uuid","parseCookie","jwt","import_mongoose","mongoose","import_jsonwebtoken","import_mongoose","mongoose","bcrypt","jwt","import_jsonwebtoken","nodemailer","jwt","express","bcrypt","jwt","import_express","express","import_express","import_express","import_crypto","import_mongoose","mongoose","import_mongoose","mongoose","import_bcryptjs","import_crypto","import_express","import_mongoose","mongoose","express","bcrypt","requirePermission","import_crypto","import_common","import_common","import_common","import_passport","import_jsx_runtime","import_jsx_runtime","hasRole","import_jsx_runtime","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/express/index.ts","../src/express/auth.routes.ts","../src/config/loadConfig.ts","../src/config/index.ts","../src/core/roles.config.ts","../src/core/session.ts","../src/models/rolePermission.model.ts","../src/models/user.model.ts","../src/utils/extract.ts","../src/utils/jwt.ts","../src/middlewares/auth.middleware.ts","../src/middlewares/validators.ts","../src/models/invite.model.ts","../src/services/auth-admin.service.ts","../src/models/client.model.ts","../src/services/email.service.ts","../src/utils/cookie.ts","../src/express/dashboards.routes.ts","../src/express/email.routes.ts","../src/express/projects.routes.ts","../src/services/projects.service.ts","../src/models/moduleConnection.model.ts","../src/models/project.model.ts","../src/express/admin/admin.routes.ts","../src/core/utils.ts","../src/middlewares/requireRole.ts","../src/models/permissions.model.ts","../src/nest/index.ts","../src/middlewares/permission.middleware.ts","../src/middlewares/requirePermission.ts","../src/services/upload.service.ts","../src/nest/authx.guard.ts","../src/nest/decorators/permissions.decorator.ts","../src/nest/decorators/roles.decorator.ts","../src/nest/decorators/session.decorator.ts","../src/passport/authx.strategy.ts"],"sourcesContent":["export * as express from './express/index.js';\nexport { nest } from './nest/index.js';\n\n// Export types and utilities that might be needed\nexport { authorize, requireAuth } from './middlewares/auth.middleware.js';\nexport { requirePermission as requirePermissionLegacy } from './middlewares/permission.middleware.js';\nexport { requirePermission } from './middlewares/requirePermission.js';\nexport { requireRole } from './middlewares/requireRole.js';\nexport { AuthAdminService } from './services/auth-admin.service.js';\nexport { EmailService } from './services/email.service.js';\nexport { ProjectsService } from './services/projects.service.js';\nexport { UploadsService } from './services/upload.service.js';\n\n// Export core RBAC utilities\nexport { getPermissionsForRoles, PLATFORM_ROLES } from './core/roles.config.js';\nexport { buildSession } from './core/session.js';\nexport {\n hasAllPermissions,\n hasAllRoles,\n hasAnyPermission,\n hasAnyRole,\n hasPermission,\n hasRole,\n} from './core/utils.js';\n\n// Export NestJS components\nexport { AuthXGuard } from './nest/authx.guard.js';\nexport { Permissions } from './nest/decorators/permissions.decorator.js';\nexport { Roles } from './nest/decorators/roles.decorator.js';\nexport { AuthXSessionDecorator } from './nest/decorators/session.decorator.js';\n\n// Export Passport strategy\nexport {\n AuthXStrategy,\n createAuthXStrategy,\n} from './passport/authx.strategy.js';\n\n// // Export Next.js server components\n// export { authx } from './next/server/authx.js';\n// export { withAuthRoute } from './next/server/withAuthRoute.js';\n\n// // Export Next.js client components\n// export { AuthXProvider, useAuthXContext } from './next/client/AuthXProvider.js';\n// export { HasPermission } from './next/client/HasPermission.js';\n// export { HasRole } from './next/client/HasRole.js';\n// export { SignedIn } from './next/client/SignedIn.js';\n// export { SignedOut } from './next/client/SignedOut.js';\n// export {\n// useAuthX,\n// useHasPermission,\n// useHasRole,\n// } from './next/client/useAuthX.js';\n","export { createAuthRouter } from './auth.routes';\r\nexport { createDashboardRouter } from './dashboards.routes';\r\nexport { createEmailRouter } from './email.routes';\r\nexport { createProjectsRouter } from './projects.routes';\r\nexport { createAdminRouter } from './admin/admin.routes';\r\n","import type { AuthRouterOptions } from 'aaspai-types';\r\nimport bcrypt from 'bcryptjs';\r\nimport { randomUUID } from 'crypto';\r\nimport express, { Router, type Router as ExpressRouter } from 'express';\r\nimport jwt from 'jsonwebtoken';\r\nimport { configureAuthX } from '../config/index.js';\r\nimport { requireAuth } from '../middlewares/auth.middleware.js';\r\nimport {\r\n isPasswordStrong,\r\n validateLogin,\r\n validateResendEmail,\r\n validateResetPassword,\r\n validateSendInvite,\r\n validateSignup,\r\n} from '../middlewares/validators.js';\r\nimport { Invite } from '../models/invite.model.js';\r\nimport { OrgUser } from '../models/user.model.js';\r\nimport { AuthAdminService } from '../services/auth-admin.service.js';\r\nimport { EmailService } from '../services/email.service.js';\r\nimport { clearOpts, cookieOpts } from '../utils/cookie.js';\r\n\r\nexport function createAuthRouter(\r\n options: AuthRouterOptions = {},\r\n): ExpressRouter {\r\n if (options.config) {\r\n configureAuthX(options.config);\r\n }\r\n\r\n const r = Router();\r\n\r\n const email = new EmailService();\r\n const authAdmin = new AuthAdminService();\r\n\r\n r.use(express.json());\r\n r.use(express.urlencoded({ extended: true }));\r\n\r\n r.get('/healthz', (_req, res) =>\r\n res.json({ status: 'ok', server: 'org-server' }),\r\n );\r\n\r\n r.post('/login', validateLogin, async (req, res) => {\r\n const { email: emailAddress, password } = req.body || {};\r\n\r\n try {\r\n // 1. Find user in your DB\r\n const user = await OrgUser.findOne({ email: emailAddress })\r\n .select('+password')\r\n .lean();\r\n\r\n if (!user) {\r\n return res.status(400).json({\r\n error: 'Invalid email or password',\r\n code: 'INVALID_CREDENTIALS',\r\n });\r\n }\r\n\r\n // 2. Check if email is verified\r\n if (!user.emailVerified) {\r\n return res.status(400).json({\r\n error: 'Please verify your email before logging in.',\r\n code: 'EMAIL_NOT_VERIFIED',\r\n });\r\n }\r\n\r\n // 3. CRITICAL: Verify password with bcrypt\r\n const isPasswordValid = user.passwordHash\r\n ? await bcrypt.compare(password, user.passwordHash)\r\n : false;\r\n\r\n if (!isPasswordValid) {\r\n return res.status(400).json({\r\n error: 'Invalid email or password',\r\n code: 'INVALID_CREDENTIALS',\r\n });\r\n }\r\n\r\n // 4. Generate tokens\r\n const tokens = generateTokens(user);\r\n setAuthCookies(res, tokens);\r\n\r\n // 5. Set projectId cookie if exists\r\n if (user.projectId) {\r\n res.cookie(options.projectCookieName || 'projectId', user.projectId, {\r\n ...cookieOpts(false),\r\n httpOnly: true,\r\n } as any);\r\n }\r\n\r\n return res.json({\r\n message: 'Login successful',\r\n user: toUserResponse(user),\r\n });\r\n } catch (err: any) {\r\n console.error('Login error:', err);\r\n return res.status(500).json({ error: 'Internal server error' });\r\n }\r\n });\r\n\r\n r.post('/signup', validateSignup, async (req, res) => {\r\n const {\r\n firstName,\r\n lastName,\r\n email: emailAddress,\r\n password,\r\n projectId,\r\n metadata,\r\n } = req.body || {};\r\n\r\n try {\r\n const kcUser = await authAdmin.createUserInRealm({\r\n username: emailAddress,\r\n email: emailAddress,\r\n firstName,\r\n lastName,\r\n projectId,\r\n credentials: [{ type: 'password', value: password, temporary: false }],\r\n });\r\n\r\n await authAdmin.assignRealmRole(kcUser.id, 'platform_user');\r\n\r\n const user = await OrgUser.findOneAndUpdate(\r\n { email: kcUser.email },\r\n {\r\n id: kcUser.id,\r\n email: kcUser.email,\r\n firstName,\r\n lastName,\r\n projectId,\r\n metadata,\r\n roles: ['platform_user'],\r\n emailVerified: false,\r\n },\r\n { upsert: true, new: true, setDefaultsOnInsert: true },\r\n );\r\n\r\n const emailResult = await sendRateLimitedEmail({\r\n emailService: email,\r\n user,\r\n subject: 'Verify your email',\r\n html: buildVerificationTemplate(\r\n email.sign({ userId: kcUser.id, email: kcUser.email }),\r\n options,\r\n ),\r\n });\r\n\r\n if (emailResult.rateLimited) {\r\n return res.status(429).json({\r\n ok: false,\r\n error: 'Too many verification emails sent. Please try again later.',\r\n waitMs: emailResult.waitMs,\r\n });\r\n }\r\n\r\n return res.json({\r\n id: user.id,\r\n email: user.email,\r\n message: 'Verification email sent. Please check your inbox.',\r\n });\r\n } catch (err: any) {\r\n return respondWithKeycloakError(res, err, 'Signup failed');\r\n }\r\n });\r\n\r\n r.get('/me', requireAuth(), (req, res) => {\r\n return res.json((req as any).user || null);\r\n });\r\n\r\n r.post('/logout', async (_req, res) => {\r\n res.clearCookie('access_token', clearOpts() as any);\r\n res.clearCookie('refresh_token', clearOpts() as any);\r\n res.json({ ok: true });\r\n });\r\n\r\n r.put('/:userId/metadata', requireAuth(), async (req, res) => {\r\n const { userId } = req.params as any;\r\n const { metadata } = req.body || {};\r\n\r\n const user = await OrgUser.findOne({ id: userId });\r\n\r\n if (!user)\r\n return res.status(404).json({ ok: false, error: 'User not found' });\r\n\r\n const map = new Map<string, any>(\r\n ((user as any).metadata || []).map((m: any) => [m.key, m.value]),\r\n );\r\n\r\n for (const item of metadata || []) map.set(item.key, item.value);\r\n (user as any).metadata = Array.from(map.entries()).map(([key, value]) => ({\r\n key,\r\n value,\r\n }));\r\n\r\n await (user as any).save();\r\n res.json({ ok: true, metadata: (user as any).metadata });\r\n });\r\n\r\n r.get('/verify-email', async (req, res) => {\r\n const token = String(req.query.token || '');\r\n if (!token) {\r\n return res.status(400).json({ error: 'Verification token is required' });\r\n }\r\n try {\r\n const payload = email.verify<{ email: string; userId: string }>(token);\r\n await authAdmin.updateUserEmailVerified(payload.userId, true);\r\n await OrgUser.updateOne(\r\n { id: payload.userId },\r\n { $set: { emailVerified: true } },\r\n );\r\n res.json({ ok: true, message: 'Email verified' });\r\n } catch (err: any) {\r\n res\r\n .status(400)\r\n .json({ ok: false, error: err?.message || 'Invalid token' });\r\n }\r\n });\r\n\r\n r.post(\r\n '/resend-verification-email',\r\n validateResendEmail,\r\n async (req, res) => {\r\n const user = await OrgUser.findOne({ email: req.body.email });\r\n if (!user)\r\n return res.status(404).json({ ok: false, error: 'User not found' });\r\n\r\n const verified = await authAdmin.isUserEmailVerified(user.id);\r\n if (verified) {\r\n return res\r\n .status(400)\r\n .json({ ok: false, error: 'Email is already verified' });\r\n }\r\n\r\n const token = email.sign({\r\n email: user.email,\r\n userId: user.id,\r\n });\r\n\r\n const resendResult = await sendRateLimitedEmail({\r\n emailService: email,\r\n user,\r\n subject: 'Verify your email',\r\n html: buildVerificationTemplate(token, options),\r\n });\r\n\r\n if (resendResult.rateLimited) {\r\n return res.status(429).json({\r\n ok: false,\r\n error: 'Too many verification emails sent. Please try again later.',\r\n waitMs: resendResult.waitMs,\r\n });\r\n }\r\n\r\n res.json({ ok: true });\r\n },\r\n );\r\n\r\n r.post('/forgot-password', validateResendEmail, async (req, res) => {\r\n const user = await OrgUser.findOne({ email: req.body.email });\r\n if (!user)\r\n return res.status(404).json({ ok: false, error: 'User not found' });\r\n\r\n const resetToken = email.sign(\r\n {\r\n userId: user.id,\r\n email: user.email,\r\n firstName: user.firstName,\r\n lastName: user.lastName,\r\n },\r\n 60 * 60,\r\n );\r\n\r\n const resetResult = await sendRateLimitedEmail({\r\n emailService: email,\r\n user,\r\n subject: 'Reset password',\r\n html: buildResetTemplate(resetToken, options),\r\n });\r\n\r\n if (resetResult.rateLimited) {\r\n return res.status(429).json({\r\n ok: false,\r\n error: 'Please wait before requesting another password reset email.',\r\n waitMs: resetResult.waitMs,\r\n });\r\n }\r\n\r\n res.json({ ok: true, message: 'Password reset email sent' });\r\n });\r\n\r\n r.post('/reset-password', validateResetPassword, async (req, res) => {\r\n const { token, newPassword } = (req.body || {}) as any;\r\n try {\r\n const payload = email.verify<{\r\n userId: string;\r\n email: string;\r\n iat: number;\r\n }>(token);\r\n\r\n const user = await OrgUser.findOne({ keycloakId: payload.userId });\r\n if (!user) {\r\n return res.status(404).json({ ok: false, error: 'User not found' });\r\n }\r\n\r\n if (\r\n user.lastPasswordReset &&\r\n payload.iat * 1000 < user.lastPasswordReset.getTime()\r\n ) {\r\n return res.status(400).json({\r\n ok: false,\r\n error:\r\n 'This reset link has already been used. Please request a new one.',\r\n });\r\n }\r\n\r\n await authAdmin.updateUserPassword(payload.userId, newPassword);\r\n\r\n user.lastPasswordReset = new Date();\r\n await user.save();\r\n\r\n res.json({ ok: true, message: 'Password updated successfully' });\r\n } catch (err: any) {\r\n res\r\n .status(400)\r\n .json({ ok: false, error: err?.message || 'Invalid or expired token' });\r\n }\r\n });\r\n\r\n r.post(\r\n '/send-invite',\r\n requireAuth(),\r\n validateSendInvite,\r\n async (req, res) => {\r\n const { email: emailAddress, role } = req.body || {};\r\n\r\n const existingUser = await OrgUser.findOne({ email: emailAddress });\r\n if (existingUser) {\r\n return res\r\n .status(400)\r\n .json({ ok: false, error: 'User with this email already exists' });\r\n }\r\n\r\n const existingInvite = await Invite.findOne({\r\n email: emailAddress,\r\n isUsed: false,\r\n isExpired: false,\r\n });\r\n\r\n if (existingInvite) {\r\n return res.status(400).json({\r\n ok: false,\r\n error: 'An active invite already exists for this email',\r\n });\r\n }\r\n\r\n const token = email.sign({\r\n email: emailAddress,\r\n role,\r\n inviteId: randomUUID(),\r\n });\r\n\r\n const invite = await Invite.create({\r\n id: token,\r\n email: emailAddress,\r\n role,\r\n invitedBy: (req as any).user?.sub,\r\n isUsed: false,\r\n expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),\r\n });\r\n\r\n await email.send(\r\n emailAddress,\r\n 'You are invited',\r\n `<a href=\"${getFrontendBaseUrl(options)}/auth/accept-invite?token=${token}\">Accept</a>`,\r\n );\r\n\r\n res.json({\r\n ok: true,\r\n inviteId: invite.id,\r\n email: invite.email,\r\n role: invite.role,\r\n expiresAt: invite.expiresAt,\r\n });\r\n },\r\n );\r\n\r\n r.get('/accept-invite', async (req, res) => {\r\n const inv = await Invite.findOne({ id: String(req.query.token) });\r\n res.json({ ok: !!inv && !(inv as any).isUsed && !(inv as any).isExpired });\r\n });\r\n\r\n r.post('/accept-invite', async (req, res) => {\r\n const { token, firstName, lastName, password, projectId } = req.body || {};\r\n\r\n if (\r\n !token ||\r\n !firstName ||\r\n !lastName ||\r\n !isPasswordStrong(password || '')\r\n ) {\r\n return res.status(400).json({ ok: false, error: 'Invalid payload' });\r\n }\r\n\r\n const invite = await Invite.findOne({\r\n id: token,\r\n isUsed: false,\r\n isExpired: false,\r\n });\r\n\r\n if (!invite) {\r\n return res\r\n .status(400)\r\n .json({ ok: false, error: 'Invitation not found or already used' });\r\n }\r\n\r\n if (invite.expiresAt && invite.expiresAt.getTime() < Date.now()) {\r\n invite.isExpired = true;\r\n await invite.save();\r\n return res\r\n .status(400)\r\n .json({ ok: false, error: 'Invitation has expired' });\r\n }\r\n\r\n try {\r\n const kcUser = await authAdmin.createUserInRealm({\r\n username: invite.email,\r\n email: invite.email,\r\n firstName,\r\n lastName,\r\n projectId,\r\n emailVerified: true,\r\n credentials: [{ type: 'password', value: password, temporary: false }],\r\n });\r\n\r\n await authAdmin.assignRealmRole(kcUser.id, invite.role);\r\n\r\n await OrgUser.findOneAndUpdate(\r\n { email: invite.email },\r\n {\r\n id: kcUser.id,\r\n email: invite.email,\r\n firstName,\r\n lastName,\r\n roles: [invite.role],\r\n emailVerified: true,\r\n },\r\n { upsert: true, new: true, setDefaultsOnInsert: true },\r\n );\r\n\r\n invite.isUsed = true;\r\n invite.usedAt = new Date();\r\n invite.usedBy = kcUser.id;\r\n await invite.save();\r\n\r\n res.json({\r\n ok: true,\r\n message: 'Account created successfully.',\r\n email: invite.email,\r\n });\r\n } catch (err: any) {\r\n res.status(400).json({\r\n ok: false,\r\n error:\r\n err?.response?.data?.error_description ||\r\n err?.message ||\r\n 'Failed to create account',\r\n });\r\n }\r\n });\r\n\r\n r.get('/invites', requireAuth(), async (_req, res) => {\r\n const invites = await Invite.find().sort({ createdAt: -1 }).lean();\r\n res.json(invites);\r\n });\r\n\r\n r.delete('/invites/:inviteId', requireAuth(), async (req, res) => {\r\n await Invite.deleteOne({ id: req.params.inviteId });\r\n res.json({ ok: true });\r\n });\r\n\r\n r.get('/get-user-by-email', async (req, res) => {\r\n const user = await OrgUser.findOne({ email: req.query.email }).lean();\r\n res.json(user || null);\r\n });\r\n\r\n r.get('/google', async (_req, res) => {\r\n res.json({ url: '/auth/google/callback?code=demo' });\r\n });\r\n\r\n r.get('/google/callback', async (_req, res) => {\r\n res.cookie(\r\n 'access_token',\r\n 'ACCESS.TOKEN.PLACEHOLDER',\r\n cookieOpts(false) as any,\r\n );\r\n res.redirect('/');\r\n });\r\n\r\n r.get('/get-users', async (req, res) => {\r\n const user = await OrgUser.find({ projectId: req.query.projectId }).lean();\r\n res.json(user || null);\r\n });\r\n\r\n return r;\r\n}\r\n\r\nfunction setAuthCookies(res: any, tokens: any) {\r\n if (tokens?.access_token) {\r\n res.cookie('access_token', tokens.access_token, {\r\n httpOnly: true,\r\n secure: false,\r\n sameSite: 'lax',\r\n maxAge: 24 * 60 * 60 * 1000, // 24 hours\r\n path: '/',\r\n });\r\n }\r\n if (tokens?.refresh_token) {\r\n res.cookie('refresh_token', tokens.refresh_token, {\r\n httpOnly: true,\r\n secure: false,\r\n sameSite: 'lax',\r\n maxAge: 24 * 60 * 60 * 1000, // 24 hours\r\n path: '/',\r\n });\r\n }\r\n}\r\n\r\nfunction toUserResponse(user: any) {\r\n if (!user) return null;\r\n return {\r\n sub: user.id || user.keycloakId,\r\n email: user.email,\r\n firstName: user.firstName,\r\n lastName: user.lastName,\r\n projectId: user.projectId,\r\n metadata: user.metadata,\r\n roles: user.roles,\r\n };\r\n}\r\n\r\nfunction respondWithKeycloakError(\r\n res: any,\r\n err: any,\r\n fallback: string,\r\n status = 400,\r\n) {\r\n const description =\r\n err?.response?.data?.error_description ||\r\n err?.response?.data?.errorMessage ||\r\n err?.message ||\r\n fallback;\r\n return res.status(status).json({ ok: false, error: description });\r\n}\r\n\r\nfunction buildVerificationTemplate(token: string, options: AuthRouterOptions) {\r\n return `<a href=\"${getFrontendBaseUrl(options)}/auth/verify-email?token=${token}\">Verify</a>`;\r\n}\r\n\r\nfunction buildResetTemplate(token: string, options: AuthRouterOptions) {\r\n return `<a href=\"${getFrontendBaseUrl(options)}/auth/reset-password?token=${token}\">Reset</a>`;\r\n}\r\n\r\nfunction getFrontendBaseUrl(options: AuthRouterOptions) {\r\n if (options.frontendBaseUrl)\r\n return options.frontendBaseUrl.replace(/\\/$/, '');\r\n const domain = process.env.ORG_DOMAIN!?.replace(/\\/$/, '');\r\n if (!domain) return '';\r\n return domain.startsWith('http') ? domain : `https://${domain}`;\r\n}\r\n\r\nasync function sendRateLimitedEmail({\r\n emailService,\r\n user,\r\n subject,\r\n html,\r\n}: {\r\n emailService: EmailService;\r\n user: any;\r\n subject: string;\r\n html: string;\r\n}): Promise<{ rateLimited: boolean; waitMs?: number }> {\r\n const can = emailService.canSend(user?.lastEmailSent || []);\r\n if (!can.ok) {\r\n return { rateLimited: true, waitMs: (can as any).waitMs };\r\n }\r\n\r\n await emailService.send(user.email, subject, html);\r\n user.lastEmailSent = [...(user.lastEmailSent || []), new Date()];\r\n await user.save();\r\n return { rateLimited: false };\r\n}\r\n\r\nfunction generateTokens(user: any) {\r\n const accessPayload = {\r\n sub: user.id.toString(),\r\n email: user.email,\r\n roles: user.roles || [],\r\n orgId: user.orgId || null,\r\n org_id: user.orgId || null,\r\n projectId: user.projectId || null,\r\n type: 'user',\r\n };\r\n\r\n const accessToken = jwt.sign(accessPayload, process.env.JWT_SECRET!, {\r\n expiresIn: '1h',\r\n });\r\n\r\n const refreshToken = jwt.sign(\r\n { sub: user._id.toString() },\r\n process.env.JWT_SECRET!,\r\n { expiresIn: '30d' },\r\n );\r\n\r\n return { access_token: accessToken, refresh_token: refreshToken };\r\n}\r\n","import type {\n AuthXConfig,\n AwsConfig,\n CookieConfig,\n EmailConfig,\n OidcConfig,\n} from 'aaspai-types';\n\nexport function loadConfig(): AuthXConfig {\n return {\n orgDomain: process.env.ORG_DOMAIN!,\n orgId: process.env.ORG_ID!,\n email: {\n host: process.env.EMAIL_HOST || 'smtp.postmarkapp.com',\n port: process.env.EMAIL_PORT ? Number(process.env.EMAIL_PORT) : 587,\n secure: (process.env.EMAIL_SECURE || 'false') === 'true',\n user: process.env.EMAIL_USER!,\n pass: process.env.EMAIL_PASSWORD!,\n from: process.env.EMAIL_FROM!,\n jwtSecret: process.env.EMAIL_JWT_SECRET!,\n } as EmailConfig,\n cookies: {\n domain: process.env.COOKIE_DOMAIN!,\n secure: (process.env.COOKIE_SECURE || 'true') === 'true',\n accessTtlMs: 24 * 60 * 60 * 1000,\n refreshTtlMs: 7 * 24 * 60 * 60 * 1000,\n } as CookieConfig,\n oidc: {\n jwtSecret: process.env.JWT_SECRET!,\n } as OidcConfig,\n aws: {\n bucket: process.env.AWS_S3_BUCKET!,\n region: process.env.AWS_REGION!,\n accessKeyId: process.env.AWS_ACCESS_KEY_ID!,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,\n } as AwsConfig,\n };\n}\n","import type {\n AuthXConfig,\n AwsConfig,\n CookieConfig,\n DeepPartial,\n EmailConfig,\n OidcConfig,\n} from 'aaspai-types';\nimport { loadConfig } from './loadConfig.js';\n\nexport type {\n AuthXConfig,\n AwsConfig,\n CookieConfig,\n DeepPartial,\n EmailConfig,\n OidcConfig,\n};\n\nexport const config: AuthXConfig = loadConfig();\n\nexport function configureAuthX(\n overrides: DeepPartial<AuthXConfig> = {},\n): AuthXConfig {\n return deepMerge(config, overrides);\n}\n\nexport function getConfig(): AuthXConfig {\n return config;\n}\n\nfunction deepMerge<T extends Record<string, any>>(\n target: T,\n source: DeepPartial<T>,\n): T {\n if (!source) {\n return target;\n }\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const value = source[key];\n if (value === undefined) continue;\n\n if (Array.isArray(value)) {\n (target as any)[key] = [...value];\n continue;\n }\n\n if (isPlainObject(value)) {\n if (!isPlainObject(target[key])) {\n (target as any)[key] = {};\n }\n deepMerge(target[key] as Record<string, any>, value as any);\n continue;\n }\n\n (target as any)[key] = value;\n }\n\n return target;\n}\n\nfunction isPlainObject(value: any): value is Record<string, any> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","export const PLATFORM_ROLES = [\r\n {\r\n role: 'platform_admin',\r\n permissions: [],\r\n },\r\n {\r\n role: 'platform_manager',\r\n permissions: [],\r\n },\r\n {\r\n role: 'platform_user',\r\n permissions: [],\r\n },\r\n];\r\n\r\n/**\r\n * Get all permissions for a given set of roles\r\n * @param roles - Array of role names\r\n * @returns Array of unique permission strings\r\n */\r\nexport function getPermissionsForRoles(roles: string[]): string[] {\r\n if (!Array.isArray(roles) || roles.length === 0) {\r\n return [];\r\n }\r\n\r\n const permissionSet = new Set<string>();\r\n\r\n for (const roleName of roles) {\r\n const roleConfig = PLATFORM_ROLES.find((r) => r.role === roleName);\r\n if (roleConfig && Array.isArray(roleConfig.permissions)) {\r\n for (const perm of roleConfig.permissions) {\r\n permissionSet.add(perm);\r\n }\r\n }\r\n }\r\n\r\n return Array.from(permissionSet);\r\n}\r\n","import type { AuthXSession } from 'aaspai-types';\r\nimport { getPermissionsForRoles } from './roles.config.js';\r\n\r\n/**\r\n * Build a canonical AuthXSession from a JWT payload or user object\r\n * @param payload - JWT payload or user object from existing auth middleware\r\n * @returns AuthXSession with standardized shape\r\n */\r\nexport function buildSession(payload: any): AuthXSession {\r\n // Extract user ID (sub is standard JWT claim)\r\n const userId = payload?.sub || payload?.userId || payload?.id || '';\r\n\r\n // Extract email\r\n const email = payload?.email || payload?.email_address || '';\r\n\r\n // Extract roles from various possible locations\r\n const roles =\r\n payload?.realm_access?.roles ||\r\n payload?.roles ||\r\n payload?.['cognito:groups'] ||\r\n (Array.isArray(payload?.role) ? payload.role : []) ||\r\n [];\r\n\r\n // Ensure roles is an array of strings\r\n const normalizedRoles = Array.isArray(roles)\r\n ? roles.map(String).filter(Boolean)\r\n : [];\r\n\r\n // Derive permissions from roles using PLATFORM_ROLES config\r\n const permissions = getPermissionsForRoles(normalizedRoles);\r\n\r\n // Build base session\r\n const session: AuthXSession = {\r\n userId,\r\n email,\r\n roles: normalizedRoles,\r\n permissions,\r\n };\r\n\r\n // Preserve optional fields if present\r\n if (payload?.projectId) session.projectId = payload.projectId;\r\n if (payload?.orgId) session.orgId = payload.orgId;\r\n if (payload?.org_id) session.org_id = payload.org_id;\r\n if (payload?.authType) session.authType = payload.authType;\r\n\r\n // Preserve any other custom fields\r\n Object.keys(payload || {}).forEach((key) => {\r\n if (\r\n ![\r\n 'sub',\r\n 'userId',\r\n 'id',\r\n 'email',\r\n 'email_address',\r\n 'realm_access',\r\n 'roles',\r\n 'cognito:groups',\r\n 'role',\r\n 'projectId',\r\n 'orgId',\r\n 'org_id',\r\n 'authType',\r\n ].includes(key)\r\n ) {\r\n session[key] = payload[key];\r\n }\r\n });\r\n\r\n return session;\r\n}\r\n","// src/models/rolePermission.model.ts\r\nimport mongoose, { Document, Schema } from 'mongoose';\r\n\r\nexport interface RolePermissionDocument extends Document {\r\n orgId?: string | null; // null => platform-wide\r\n role: string; // \"platform_admin\", \"platform_manager\", \"custom_role\"\r\n permissions: string[]; // list of permission keys\r\n createdAt: Date;\r\n updatedAt: Date;\r\n}\r\n\r\nconst RolePermissionSchema = new Schema<RolePermissionDocument>(\r\n {\r\n orgId: { type: String, default: null, index: true },\r\n role: { type: String, required: true },\r\n permissions: { type: [String], default: [] },\r\n },\r\n {\r\n timestamps: true,\r\n },\r\n);\r\n\r\nRolePermissionSchema.index({ orgId: 1, role: 1 }, { unique: true });\r\n\r\nexport const RolePermissionModel = mongoose.model<RolePermissionDocument>(\r\n 'RolePermission',\r\n RolePermissionSchema,\r\n 'role_permissions',\r\n);\r\n","import mongoose from 'mongoose';\nimport { v4 as uuid } from 'uuid';\n\nconst MetadataSchema = new mongoose.Schema(\n {\n key: { type: String, required: true },\n value: { type: mongoose.Schema.Types.Mixed, required: true },\n },\n { _id: false },\n);\n\nconst OrgUserSchema = new mongoose.Schema(\n {\n id: { type: String, default: uuid(), index: true },\n email: { type: String, required: true, unique: true },\n firstName: { type: String, required: true },\n lastName: { type: String, required: true },\n orgId: { type: String },\n projectId: { type: String, required: true },\n roles: { type: [String], default: [] },\n emailVerified: { type: Boolean, default: false },\n lastEmailSent: { type: [Date], default: [] },\n lastPasswordReset: { type: Date },\n metadata: { type: [MetadataSchema], default: [] },\n passwordHash: { type: String },\n },\n { timestamps: true, collection: 'users' },\n);\n\nexport const OrgUser = mongoose.model('OrgUser', OrgUserSchema);\n","import { parse as parseCookie } from 'cookie';\nimport type { Request } from 'express';\n\nexport function extractToken(\n req: Request,\n opts?: {\n headerNames?: string[];\n cookieNames?: string[];\n queryNames?: string[];\n },\n) {\n const headerNames = opts?.headerNames ?? ['authorization', 'token'];\n const cookieNames = opts?.cookieNames ?? ['access_token', 'authorization'];\n const queryNames = opts?.queryNames ?? ['access_token', 'token'];\n\n for (const h of headerNames) {\n const raw = (req.headers as any)[h] as string | undefined;\n if (raw) {\n const lower = raw.toLowerCase();\n if (lower.startsWith('bearer ')) return raw.slice(7).trim();\n if (!raw.includes(' ')) return raw.trim();\n }\n }\n\n const ch = req.headers['cookie'];\n\n if (typeof ch === 'string') {\n const parsed = parseCookie(ch);\n for (const c of cookieNames) if (parsed[c]) return parsed[c];\n }\n\n for (const q of queryNames) {\n const v = (req.query as any)?.[q];\n if (typeof v === 'string' && v) return v;\n }\n\n return null;\n}\n\nexport function readProjectId(req: Request) {\n const ch = req.headers['cookie'];\n\n if (typeof ch === 'string') {\n try {\n const parsed = parseCookie(ch);\n return parsed['projectId'] || null;\n } catch {}\n }\n\n return null;\n}\n","import jwt from 'jsonwebtoken';\nimport { config } from '../config/index.js';\n\nexport function verifyJwt(token: string): Promise<any> {\n return new Promise((resolve, reject) => {\n jwt.verify(\n token,\n process.env.JWT_SECRET!, // This is your shared secret (string)\n {\n algorithms: ['HS256'], // Only allow HS256\n complete: false, // We only want payload\n },\n (err, decoded) => {\n if (err) {\n reject(err);\n } else {\n resolve(decoded);\n }\n },\n );\n });\n}\n\nexport function claimsToUser(payload: any) {\n return {\n sub: payload.sub,\n email: payload.email || payload.preferred_username,\n roles: payload.roles || [],\n name:\n payload.name ||\n `${payload.given_name || ''} ${payload.family_name || ''}`.trim(),\n emailVerified: payload.email_verified || false,\n };\n}\n","import type { AuthXSession } from 'aaspai-types';\r\nimport type { NextFunction, Request, Response } from 'express';\r\nimport { buildSession } from '../core/session.js';\r\nimport { RolePermissionModel } from '../models/rolePermission.model.js';\r\nimport { OrgUser } from '../models/user.model.js';\r\nimport { extractToken, readProjectId } from '../utils/extract.js';\r\nimport { verifyJwt } from '../utils/jwt.js';\r\n\r\nasync function mergeRolePermissions(session: AuthXSession): Promise<void> {\r\n const roles = Array.isArray(session.roles) ? session.roles : [];\r\n if (!roles.length) return;\r\n\r\n const orgContexts = new Set<string | null>();\r\n if (session.orgId) orgContexts.add(session.orgId);\r\n if (session.org_id) orgContexts.add(session.org_id);\r\n if (session.projectId) orgContexts.add(session.projectId);\r\n orgContexts.add(null);\r\n\r\n const docs = await RolePermissionModel.find({\r\n orgId: { $in: Array.from(orgContexts) },\r\n role: { $in: roles },\r\n })\r\n .lean()\r\n .exec();\r\n\r\n const dynamic = new Set<string>();\r\n for (const doc of docs) {\r\n for (const perm of doc.permissions || []) {\r\n if (perm) dynamic.add(perm);\r\n }\r\n }\r\n\r\n const existing = Array.isArray(session.permissions) ? session.permissions : [];\r\n session.permissions = Array.from(new Set([...existing, ...dynamic]));\r\n}\r\n\r\n/**\r\n * Express middleware to require authentication\r\n * Extracts and verifies JWT token, builds AuthXSession, and attaches to req.user\r\n */\r\nexport function requireAuth() {\r\n return async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n // Check for API key first (for backward compatibility)\r\n const apiKey = (req.headers['x-api-key'] || req.headers['x-apikey']) as\r\n | string\r\n | undefined;\r\n\r\n const userId = (req.headers['x-user-id'] || req.headers['x-userId']) as\r\n | string\r\n | undefined;\r\n\r\n if (apiKey) {\r\n if (apiKey !== process.env.SERVER_API_KEY) {\r\n return res.status(401).json({ error: 'Invalid API key' });\r\n }\r\n\r\n if (!userId) {\r\n return res.status(401).json({ error: 'User Id is Required' });\r\n }\r\n\r\n // Fetch real user from DB\r\n const user = await OrgUser.findOne({ id: userId }).lean();\r\n\r\n if (!user) {\r\n return res.status(401).json({ error: 'User not found' });\r\n }\r\n\r\n const session = buildSession({\r\n sub: user.id.toString(),\r\n email: user.email,\r\n roles: user.roles || [],\r\n orgId: user.orgId,\r\n org_id: user.orgId,\r\n projectId: user.projectId,\r\n });\r\n\r\n session.authType = 'api-key';\r\n session.projectId = readProjectId(req) || user.projectId || undefined;\r\n await mergeRolePermissions(session);\r\n (req as any).user = session;\r\n return next();\r\n } else {\r\n // Extract and verify JWT token\r\n const token = extractToken(req);\r\n if (!token) {\r\n return res.status(401).json({ error: 'Missing token' });\r\n }\r\n const claims = await verifyJwt(token);\r\n const session = buildSession(claims);\r\n // Preserve projectId if present in cookie\r\n const pid = readProjectId(req);\r\n if (pid) session.projectId = pid;\r\n await mergeRolePermissions(session);\r\n\r\n // Attach session to request\r\n (req as any).user = session;\r\n next();\r\n }\r\n } catch (e: any) {\r\n res.status(401).json({ error: e?.message || 'Unauthorized' });\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Express middleware to require one or more roles\r\n * @param roles - Array of role names (user must have at least one)\r\n * @deprecated Use requireRole from middlewares instead. This is kept for backward compatibility.\r\n */\r\nexport function authorize(roles: string[] = []) {\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n if (!roles || roles.length === 0) return next();\r\n const user = (req as any).user as AuthXSession | undefined;\r\n if (!user) {\r\n return res.status(401).json({ error: 'Unauthorized' });\r\n }\r\n const have = new Set<string>((user.roles || []).map(String));\r\n const ok = roles.some((r) => have.has(r));\r\n if (!ok) {\r\n return res\r\n .status(403)\r\n .json({ error: `Requires one of roles: ${roles.join(', ')}` });\r\n }\r\n next();\r\n };\r\n}\r\n","export function isEmail(v: string) {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(v);\n}\n\nexport function isPasswordStrong(v: string) {\n return (\n typeof v === 'string' &&\n v.length >= 6 &&\n /[A-Z]/.test(v) &&\n /[^a-zA-Z0-9]/.test(v)\n );\n}\n\nexport function validateSignup(req: any, res: any, next: any) {\n const { firstName, lastName, email, password, projectId, metadata } =\n req.body || {};\n if (!firstName || !lastName)\n return res.status(400).json({ error: 'firstName,lastName required' });\n if (!isEmail(email)) return res.status(400).json({ error: 'invalid email' });\n if (!isPasswordStrong(password))\n return res.status(400).json({ error: 'weak password' });\n if (!projectId) return res.status(400).json({ error: 'projectId required' });\n if (!Array.isArray(metadata))\n return res.status(400).json({ error: 'metadata must be array' });\n next();\n}\n\nexport function validateLogin(req: any, res: any, next: any) {\n const { email, password } = req.body || {};\n if (!isEmail(email)) return res.status(400).json({ error: 'invalid email' });\n if (typeof password !== 'string')\n return res.status(400).json({ error: 'password required' });\n next();\n}\n\nexport function validateResetPassword(req: any, res: any, next: any) {\n const { token, newPassword } = req.body || {};\n if (!token) return res.status(400).json({ error: 'token required' });\n if (!isPasswordStrong(newPassword))\n return res.status(400).json({ error: 'weak password' });\n next();\n}\n\nexport function validateResendEmail(req: any, res: any, next: any) {\n const { email } = req.body || {};\n if (!isEmail(email)) return res.status(400).json({ error: 'invalid email' });\n next();\n}\n\nexport function validateSendInvite(req: any, res: any, next: any) {\n const { email, role } = req.body || {};\n if (!isEmail(email)) return res.status(400).json({ error: 'invalid email' });\n if (!['platform_user', 'org_admin'].includes(role))\n return res.status(400).json({ error: 'invalid role' });\n next();\n}\n","import mongoose from 'mongoose';\n\nconst InviteSchema = new mongoose.Schema(\n {\n id: { type: String, required: true, index: true },\n email: { type: String, required: true },\n role: {\n type: String,\n enum: ['platform_user', 'org_admin'],\n required: true,\n },\n invitedBy: { type: String },\n usedBy: { type: String },\n isUsed: { type: Boolean, default: false },\n usedAt: { type: Date },\n expiresAt: { type: Date },\n isExpired: { type: Boolean, default: false },\n },\n { timestamps: true, collection: 'invites' },\n);\n\nexport const Invite = mongoose.model('Invite', InviteSchema);\n","import bcrypt from 'bcrypt';\r\nimport jwt from 'jsonwebtoken';\r\nimport { config } from '../config/index.js';\r\nimport { ClientModel } from '../models/client.model.js';\r\nimport { RolePermissionModel } from '../models/rolePermission.model.js';\r\nimport { OrgUser } from '../models/user.model.js';\r\n\r\nexport class AuthAdminService {\r\n private token?: { accessToken: string; exp: number };\r\n\r\n async getAdminToken() {\r\n return this.ensureAdminToken();\r\n }\r\n\r\n // -------------------------------------------------------------------\r\n // CLIENTS\r\n // -------------------------------------------------------------------\r\n async createClient(\r\n clientId: string,\r\n redirectUris: string[] = [],\r\n publicClient = false,\r\n ) {\r\n const client = await ClientModel.create({\r\n clientId,\r\n redirectUris,\r\n publicClient,\r\n });\r\n return client;\r\n }\r\n\r\n async updateClient(id: string, patch: any) {\r\n await ClientModel.findByIdAndUpdate(id, patch);\r\n }\r\n\r\n // -------------------------------------------------------------------\r\n // USERS\r\n // -------------------------------------------------------------------\r\n async listUsersInRealm(\r\n _realm: string,\r\n filter?: { email?: string; username?: string },\r\n ) {\r\n return OrgUser.find(filter || {});\r\n }\r\n\r\n async getUserById(userId: string) {\r\n return OrgUser.findOne({ id: userId });\r\n }\r\n\r\n async isUserEmailVerified(userId: string) {\r\n const user: any = await OrgUser.findOne({ id: userId });\r\n return user?.emailVerified;\r\n }\r\n\r\n async createUserInRealm(payload: {\r\n username: string;\r\n email: string;\r\n firstName: string;\r\n projectId: string;\r\n lastName?: string;\r\n credentials?: any[];\r\n emailVerified?: boolean;\r\n }) {\r\n const hashedPassword = payload.credentials?.[0]?.value\r\n ? await bcrypt.hash(payload.credentials[0].value, 10)\r\n : undefined;\r\n\r\n const user = await OrgUser.create({\r\n username: payload.username,\r\n email: payload.email,\r\n firstName: payload.firstName,\r\n lastName: payload.lastName,\r\n projectId: payload.projectId,\r\n emailVerified: payload.emailVerified || false,\r\n passwordHash: hashedPassword,\r\n enabled: true,\r\n });\r\n\r\n return user;\r\n }\r\n\r\n async assignRealmRole(userId: string, roleName: string) {\r\n const role = await RolePermissionModel.findOne({ role: roleName });\r\n if (!role) throw new Error(`Role not found: ${roleName}`);\r\n\r\n await OrgUser.findOneAndUpdate(\r\n { id: userId },\r\n {\r\n $addToSet: { roles: role._id },\r\n },\r\n );\r\n }\r\n\r\n async updateUserEmailVerified(userId: string, emailVerified: boolean) {\r\n await OrgUser.findOneAndUpdate({ id: userId }, { emailVerified });\r\n }\r\n\r\n async updateUserPassword(userId: string, newPassword: string) {\r\n const hashed = await bcrypt.hash(newPassword, 10);\r\n await OrgUser.findOneAndUpdate({ id: userId }, { password: hashed });\r\n }\r\n\r\n // -------------------------------------------------------------------\r\n // ADMIN TOKEN (self-issued JWT)\r\n // -------------------------------------------------------------------\r\n private async ensureAdminToken(): Promise<string> {\r\n const now = Math.floor(Date.now() / 1000);\r\n\r\n if (this.token && this.token.exp - 30 > now) {\r\n return this.token.accessToken;\r\n }\r\n\r\n const payload = {\r\n type: 'admin',\r\n system: true,\r\n };\r\n\r\n const accessToken = jwt.sign(payload, process.env.JWT_SECRET!, {\r\n expiresIn: '1h',\r\n });\r\n\r\n this.token = {\r\n accessToken,\r\n exp: now + 3600,\r\n };\r\n\r\n return this.token.accessToken;\r\n }\r\n}\r\n","import mongoose, { Document, Model, Schema } from 'mongoose';\r\n\r\nexport interface IClient extends Document {\r\n clientId: string;\r\n redirectUris: string[];\r\n publicClient: boolean;\r\n secret?: string; // optional — used only for confidential clients\r\n createdAt: Date;\r\n updatedAt: Date;\r\n}\r\n\r\nconst ClientSchema = new Schema<IClient>(\r\n {\r\n clientId: {\r\n type: String,\r\n required: true,\r\n unique: true,\r\n index: true,\r\n },\r\n\r\n redirectUris: {\r\n type: [String],\r\n default: [],\r\n },\r\n\r\n publicClient: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n\r\n // Optional: if you want confidential clients\r\n secret: {\r\n type: String,\r\n required: function (this: IClient) {\r\n return !this.publicClient;\r\n },\r\n },\r\n },\r\n {\r\n timestamps: true,\r\n },\r\n);\r\n\r\nexport const ClientModel: Model<IClient> =\r\n mongoose.models.Client || mongoose.model<IClient>('Client', ClientSchema);\r\n","import jwt from 'jsonwebtoken';\nimport nodemailer from 'nodemailer';\nimport { config } from '../config/index.js';\n\nexport class EmailService {\n private transporter;\n private MAX_EMAILS = 5;\n private WINDOW_MINUTES = 15;\n private BLOCK_HOURS = 1;\n constructor() {\n this.transporter = nodemailer.createTransport({\n host: process.env.EMAIL_HOST || 'smtp.postmarkapp.com',\n port: process.env.EMAIL_PORT ? Number(process.env.EMAIL_PORT) : 587,\n secure: (process.env.EMAIL_SECURE || 'false') === 'true',\n auth: { user: process.env.EMAIL_USER!, pass: process.env.EMAIL_PASSWORD! },\n });\n }\n\n sign(payload: any, ttlSec = 60 * 60 * 24) {\n return jwt.sign(payload, process.env.EMAIL_JWT_SECRET!, { expiresIn: ttlSec });\n }\n\n verify<T = any>(token: string): T {\n return jwt.verify(token, process.env.EMAIL_JWT_SECRET!) as T;\n }\n\n async send(to: string, subject: string, html: string) {\n await this.transporter.sendMail({\n from: process.env.EMAIL_FROM!,\n to,\n subject,\n html,\n });\n }\n\n canSend(lastEmailSent: Date[]) {\n const now = Date.now();\n const windowStart = now - this.WINDOW_MINUTES * 60 * 1000;\n const emailsInWindow = (lastEmailSent || [])\n .map((d) => new Date(d))\n .filter((d) => d.getTime() >= windowStart);\n if (emailsInWindow.length >= this.MAX_EMAILS)\n return {\n ok: false,\n reason: 'RATE_LIMIT',\n waitMs: this.BLOCK_HOURS * 60 * 60 * 1000,\n };\n return { ok: true };\n }\n}\n","import { config } from '../config/index.js';\n\nexport function cookieOpts(isRefresh = false) {\n const maxAge = isRefresh\n ? config.cookies.refreshTtlMs\n : config.cookies.accessTtlMs;\n\n const secure =\n process.env.NODE_ENV === 'production'\n ? (process.env.COOKIE_SECURE ?? true)\n : false;\n\n return {\n httpOnly: true,\n secure,\n sameSite: 'none' as const,\n domain: process.env.COOKIE_DOMAIN!,\n maxAge,\n };\n}\n\nexport function clearOpts() {\n const secure =\n process.env.NODE_ENV === 'production'\n ? (process.env.COOKIE_SECURE ?? true)\n : false;\n\n return {\n domain: process.env.COOKIE_DOMAIN!,\n sameSite: 'none' as const,\n secure,\n };\n}\n","import express, { Router, type Router as ExpressRouter } from 'express';\nimport { AuthAdminService } from '../services/auth-admin.service.js';\nimport { requireAuth } from '../middlewares/auth.middleware.js';\n\nexport function createDashboardRouter(options: any): ExpressRouter {\n const r = Router();\n const kc = new AuthAdminService();\n r.use(express.json());\n\n r.post('/', requireAuth(), async (req, res, next) => {\n try {\n const { slug, isPublic, authFlow, orgDomain } = req.body || {};\n const redirectUris = [`https://${slug}.${orgDomain}/*`];\n const created = await kc.createClient(slug, redirectUris, !!isPublic);\n if (authFlow || isPublic != null) {\n await kc.updateClient(created.id, {\n authenticationFlowBindingOverrides: authFlow\n ? { browser: authFlow }\n : undefined,\n registrationAllowed: !!isPublic,\n });\n }\n res.json({ clientId: created.clientId });\n } catch (e) {\n next(e);\n }\n });\n\n return r;\n}\n","import { Router, type Router as ExpressRouter } from 'express';\n\nexport function createEmailRouter(options: any): ExpressRouter {\n const r = Router();\n\n r.get('/verify', (req, res) =>\n res.json({ ok: true, token: req.query.token }),\n );\n\n return r;\n}\n","import { Router, type Router as ExpressRouter } from 'express';\nimport { requireAuth } from '../middlewares/auth.middleware.js';\nimport { ProjectsService } from '../services/projects.service.js';\n\nexport function createProjectsRouter(options: any): ExpressRouter {\n const r = Router();\n const svc = new ProjectsService();\n\n r.post('/create', requireAuth(), async (req, res) => {\n const { org_id, name, description } = req.body || {};\n const p = await svc.create(org_id, name, description);\n res.json(p);\n });\n\n r.get('/:org_id', requireAuth(), async (req, res) => {\n res.json(await svc.list(req.params.org_id));\n });\n\n r.get('/:org_id/:id', requireAuth(), async (req, res) => {\n res.json(await svc.get(req.params.org_id, req.params.id));\n });\n\n r.put('/:org_id/:id', requireAuth(), async (req, res) => {\n res.json(\n await svc.update(req.params.org_id, req.params.id, req.body || {}),\n );\n });\n\n r.delete('/:org_id/:id', requireAuth(), async (req, res) => {\n res.json(await svc.remove(req.params.org_id, req.params.id));\n });\n\n return r;\n}\n","import { randomUUID } from 'crypto';\nimport { ModuleConnection } from '../models/moduleConnection.model.js';\nimport { Project } from '../models/project.model.js';\n\nexport class ProjectsService {\n async create(org_id: string, name: string, description?: string) {\n const _id = randomUUID();\n const secret = randomUUID();\n const p = await Project.create({ _id, org_id, name, description, secret });\n await ModuleConnection.create({\n projectId: _id,\n modules: { data: [], integration: [], storage: [] },\n });\n return p.toObject();\n }\n\n async list(org_id: string) {\n return Project.find({ org_id }).lean();\n }\n\n async get(org_id: string, id: string) {\n return Project.findOne({ org_id, _id: id }).lean();\n }\n\n async update(org_id: string, id: string, patch: any) {\n return Project.findOneAndUpdate(\n { org_id, _id: id },\n { $set: patch },\n { new: true },\n ).lean();\n }\n\n async remove(org_id: string, id: string) {\n await Project.deleteOne({ org_id, _id: id });\n await ModuleConnection.deleteMany({ projectId: id });\n return { ok: true };\n }\n}\n","import mongoose from 'mongoose';\n\nconst ModuleItemSchema = new mongoose.Schema(\n { id: { type: String, required: true } },\n { _id: false },\n);\n\nconst ModuleConnectionSchema = new mongoose.Schema(\n {\n projectId: { type: String, required: true, index: true },\n modules: {\n data: { type: [ModuleItemSchema], default: [] },\n integration: { type: [ModuleItemSchema], default: [] },\n storage: { type: [ModuleItemSchema], default: [] },\n },\n },\n { timestamps: true, collection: 'module_connection' },\n);\n\nexport const ModuleConnection = mongoose.model(\n 'ModuleConnection',\n ModuleConnectionSchema,\n);\n","import mongoose from 'mongoose';\n\nconst ProjectSchema = new mongoose.Schema(\n {\n _id: { type: String, required: true },\n org_id: { type: String, required: true, index: true },\n name: { type: String, required: true },\n description: { type: String },\n secret: { type: String, required: true },\n },\n { timestamps: true, collection: 'projects' },\n);\n\nexport const Project = mongoose.model('Project', ProjectSchema);\n","import type { AuthUser } from 'aaspai-types';\nimport bcrypt from 'bcryptjs';\nimport { randomUUID } from 'crypto';\nimport express, { Request, Response, Router } from 'express';\nimport { requireAuth } from '../../middlewares/auth.middleware.js';\nimport { requireRole } from '../../middlewares/requireRole.js';\nimport { PermissionsModel } from '../../models/permissions.model';\nimport { RolePermissionModel } from '../../models/rolePermission.model';\nimport { OrgUser } from '../../models/user.model.js';\n\ninterface AuthenticatedRequest extends Request {\n user?: AuthUser;\n}\n\nfunction resolveOrgId(req: AuthenticatedRequest): string | null {\n const user = req.user || {};\n const fromUser = (user.orgId as string) || (user.org_id as string) || null;\n\n const fromQuery = (req.query.orgId as string) || null;\n const fromBody = (req.body && (req.body.orgId as string)) || null;\n\n return fromQuery || fromBody || fromUser;\n}\n\nfunction resolveProjectId(req: AuthenticatedRequest): string | null {\n const user = req.user || {};\n const fromUser = (user.projectId as string) || null;\n\n const fromQuery = (req.query.projectId as string) || null;\n const fromBody = (req.body && (req.body.projectId as string)) || null;\n\n return fromQuery || fromBody || fromUser;\n}\n\nexport function createAdminRouter(_options: any = {}): Router {\n const r = Router();\n\n r.use(express.json());\n r.use(express.urlencoded({ extended: true }));\n\n // All routes require platform_admin (for now).\n const adminGuards = [requireAuth(), requireRole('platform_admin')];\n\n r.post(\n '/users',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n const {\n firstName,\n lastName,\n email: emailAddress,\n password,\n emailVerified = false,\n roles = [],\n } = req.body || {};\n\n const projectId = resolveProjectId(req);\n\n try {\n const hashedPassword = password\n ? await bcrypt.hash(password, 10)\n : undefined;\n\n const user = await OrgUser.create({\n id: randomUUID(),\n email: emailAddress,\n orgId: process.env.ORG_ID!,\n firstName,\n lastName,\n projectId,\n emailVerified,\n metadata: [],\n passwordHash: hashedPassword,\n roles,\n });\n\n return res.json({\n id: user.id,\n email: user.email,\n message: 'Verification email sent. Please check your inbox.',\n });\n } catch (err: any) {\n console.error('Create user error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.delete(\n '/users',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const userId = (req?.body?.id || req?.query?.id) as string | undefined;\n\n if (!userId) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'UserId is required (send in body.id or ?id=...)',\n });\n }\n\n const deleted = await OrgUser.findOneAndDelete({ id: userId }).exec();\n\n if (!deleted) {\n return res.status(404).json({\n error: 'NOT_FOUND',\n message: 'User not found or already deleted',\n });\n }\n\n return res.status(200).json({\n ok: true,\n message: 'User deleted successfully',\n deletedUser: {\n id: deleted.id,\n firstName: deleted.firstName,\n email: deleted.email,\n orgId: deleted.orgId,\n },\n });\n } catch (err: any) {\n console.error('Delete user error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.put(\n '/users/:id',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n const userId = req.params.id;\n\n const {\n firstName,\n lastName,\n email: emailAddress,\n password,\n emailVerified,\n roles,\n } = req.body || {};\n\n try {\n const existingUser = await OrgUser.findOne({\n id: userId,\n orgId: process.env.ORG_ID!,\n });\n\n if (!existingUser) {\n return res.status(404).json({ error: 'USER_NOT_FOUND' });\n }\n\n // Only update allowed fields\n if (firstName !== undefined) existingUser.firstName = firstName;\n if (lastName !== undefined) existingUser.lastName = lastName;\n if (emailAddress !== undefined) existingUser.email = emailAddress;\n if (emailVerified !== undefined)\n existingUser.emailVerified = emailVerified;\n if (roles !== undefined) existingUser.roles = roles;\n\n // Password (if provided)\n if (password) {\n existingUser.passwordHash = await bcrypt.hash(password, 10);\n }\n\n // DO NOT UPDATE projectId — keep original value forever\n // existingUser.projectId stays as-is\n\n await existingUser.save();\n\n return res.json({\n id: existingUser.id,\n email: existingUser.email,\n message: 'User updated successfully.',\n });\n } catch (err: any) {\n console.error('Update user error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * GET /permissions\n * List API configs (permissions) for an org (or platform/global when orgId is absent).\n */\n r.get(\n '/permissions',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n\n const filter: any = {};\n if (orgId !== null) {\n filter.orgId = orgId;\n } else {\n filter.orgId = null;\n }\n\n const items = await PermissionsModel.find(filter).lean().exec();\n return res.json(items);\n } catch (err) {\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * POST /permissions\n * Create a new API config (permission).\n * Body:\n * {\n * orgId?: string,\n * key: string,\n * method: string,\n * path: string,\n * module?: string,\n * description?: string,\n * isInternal?: boolean\n * }\n *\n * Also auto-assigns this permission to platform_admin for that org.\n */\n r.post(\n '/permissions',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n\n const {\n key,\n type,\n apiId,\n description,\n isInternal = false,\n } = req.body || {};\n\n if (!key || !type) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'permission key, and permission type are required',\n });\n }\n\n const id = randomUUID();\n\n const permission = await PermissionsModel.create({\n id,\n orgId: orgId ?? null,\n key,\n type,\n apiId,\n description,\n isInternal: !!isInternal,\n });\n\n // Auto-assign to platform_admin role for this org\n await RolePermissionModel.findOneAndUpdate(\n { orgId: orgId ?? null, role: 'platform_admin' },\n { $addToSet: { permissions: key } },\n { upsert: true, new: true },\n ).exec();\n\n return res.status(201).json(permission);\n } catch (err: any) {\n if (err && err.code === 11000) {\n return res.status(409).json({\n error: 'DUPLICATE_PERMISSION',\n message: 'Permission key already exists for this org',\n });\n }\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.put(\n '/permissions/:id',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n const permissionId = req.params.id;\n\n const { key, type, apiId, description, isInternal } = req.body || {};\n // Fetch existing permission\n const existing = await PermissionsModel.findOne({\n id: permissionId,\n orgId: orgId ?? null,\n });\n\n if (!existing) {\n return res.status(404).json({\n error: 'NOT_FOUND',\n message: 'Permission does not exist',\n });\n }\n\n const oldKey = existing.key;\n\n // Apply updates\n if (key !== undefined) existing.key = key;\n if (type !== undefined) existing.type = type;\n if (apiId !== undefined) existing.apiId = apiId;\n if (description !== undefined) existing.description = description;\n if (isInternal !== undefined) existing.isInternal = !!isInternal;\n\n await existing.save();\n\n if (oldKey !== key) {\n // 1. Remove old key\n await RolePermissionModel.updateMany(\n {\n orgId: orgId ?? null,\n permissions: oldKey,\n },\n {\n $pull: { permissions: oldKey },\n },\n );\n\n // 2. Add new key\n await RolePermissionModel.updateMany(\n {\n orgId: orgId ?? null,\n },\n {\n $addToSet: { permissions: key },\n },\n );\n }\n\n return res.json(existing);\n } catch (err: any) {\n if (err && err.code === 11000) {\n return res.status(409).json({\n error: 'DUPLICATE_PERMISSION',\n message: 'Permission key already exists for this org',\n });\n }\n\n console.error('Update permission error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.delete(\n '/permissions',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const permissionId = (req?.body?.id || req?.query?.id) as\n | string\n | undefined;\n\n if (!permissionId) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'Permission id is required (send in body.id or ?id=...)',\n });\n }\n\n // Fetch permission before deletion → we need key + orgId\n const existing = await PermissionsModel.findOne({ id: permissionId });\n if (!existing) {\n return res.status(404).json({\n error: 'NOT_FOUND',\n message: 'Permission not found or already deleted',\n });\n }\n\n const { key, orgId } = existing;\n\n // Delete permission\n await PermissionsModel.deleteOne({ id: permissionId });\n\n // Remove permission key from all roles in THE SAME org\n await RolePermissionModel.updateMany(\n { orgId: orgId ?? null },\n { $pull: { permissions: key } },\n );\n\n return res.status(200).json({\n ok: true,\n message: 'Permission deleted successfully',\n deletedPermission: {\n id: existing.id,\n key: existing.key,\n type: existing.type,\n apiId: existing.apiId,\n description: existing.description,\n isInternal: existing.isInternal,\n orgId: existing.orgId,\n },\n });\n } catch (err: any) {\n console.error('Delete permission error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * GET /roles\n * List role-permissions for org.\n * Query: ?orgId=...\n */\n r.get(\n '/roles',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n\n const filter: any = {};\n if (orgId !== null) {\n filter.orgId = orgId;\n } else {\n filter.orgId = null;\n }\n\n const roles = await RolePermissionModel.find(filter).lean().exec();\n return res.json(roles);\n } catch (err) {\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * POST /roles\n * Create or replace a role's permission set.\n *\n * Body:\n * {\n * orgId?: string,\n * role: string,\n * permissions: string[]\n * }\n */\n r.post(\n '/roles',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n const { role, permissions } = req.body || {};\n\n if (!role || !Array.isArray(permissions)) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'role and permissions[] are required',\n });\n }\n\n const id = randomUUID();\n\n const doc = await RolePermissionModel.findOneAndUpdate(\n { orgId: orgId ?? null, role },\n { $set: { permissions } },\n { upsert: true, new: true },\n ).exec();\n\n return res.status(200).json(doc);\n } catch (err) {\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n r.put(\n '/roles/:id',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const orgId = resolveOrgId(req);\n const roleId = req.params.id;\n\n const { role: newRoleName, permissions } = req.body || {};\n\n if (!newRoleName || !Array.isArray(permissions)) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'role and permissions are required',\n });\n }\n\n // 1. Find the existing role\n const existing = await RolePermissionModel.findById(roleId);\n\n if (!existing) {\n return res.status(404).json({\n error: 'ROLE_NOT_FOUND',\n message: 'Role does not exist',\n });\n }\n\n const oldRoleName = existing.role;\n\n // 2. Update the role document\n existing.role = newRoleName;\n existing.permissions = permissions;\n await existing.save();\n\n if (oldRoleName !== newRoleName) {\n // Step 1 — remove old role from all users\n await OrgUser.updateMany(\n {\n orgId: orgId ?? null,\n roles: oldRoleName,\n },\n {\n $pull: { roles: oldRoleName },\n },\n );\n\n // Step 2 — add new role to users that previously had the old role\n await OrgUser.updateMany(\n {\n orgId: orgId ?? null,\n roles: { $ne: newRoleName }, // avoid duplicates\n },\n {\n $addToSet: { roles: newRoleName },\n },\n );\n }\n\n return res.status(200).json(existing);\n } catch (err) {\n console.error('Update role error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n /**\n * DELETE /roles\n * Delete a role completely (by MongoDB _id)\n *\n * Body:\n * {\n * \"id\": \"507f1f77bcf86cd799439011\" // MongoDB _id of the RolePermission document\n * }\n *\n * Query alternative (optional):\n * ?id=507f1f77bcf86cd799439011\n */\n r.delete(\n '/roles',\n ...adminGuards,\n async (req: AuthenticatedRequest, res: Response) => {\n try {\n const roleId = (req?.body?.id || req?.query?.id) as string | undefined;\n\n if (!roleId) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'Role _id is required (send in body.id or ?id=...)',\n });\n }\n\n // Optional: validate it's a valid ObjectId\n if (!/^[0-9a-fA-F]{24}$/.test(roleId)) {\n return res.status(400).json({\n error: 'VALIDATION_ERROR',\n message: 'Invalid role _id format',\n });\n }\n\n const deleted =\n await RolePermissionModel.findByIdAndDelete(roleId).exec();\n\n if (!deleted) {\n return res.status(404).json({\n error: 'NOT_FOUND',\n message: 'Role not found or already deleted',\n });\n }\n\n return res.status(200).json({\n ok: true,\n message: 'Role deleted successfully',\n deletedRole: {\n _id: deleted._id,\n role: deleted.role,\n orgId: deleted.orgId,\n },\n });\n } catch (err: any) {\n console.error('Delete role error:', err);\n return res.status(500).json({ error: 'INTERNAL_ERROR' });\n }\n },\n );\n\n return r;\n}\n","import type { AuthXSession } from 'aaspai-types';\r\n\r\n/**\r\n * Check if a session has a specific role\r\n */\r\nexport function hasRole(\r\n session: AuthXSession | null | undefined,\r\n role: string,\r\n): boolean {\r\n if (!session || !session.roles) return false;\r\n return session.roles.includes(role);\r\n}\r\n\r\n/**\r\n * Check if a session has any of the specified roles\r\n */\r\nexport function hasAnyRole(\r\n session: AuthXSession | null | undefined,\r\n roles: string[],\r\n): boolean {\r\n if (\r\n !session ||\r\n !session.roles ||\r\n !Array.isArray(roles) ||\r\n roles.length === 0\r\n ) {\r\n return false;\r\n }\r\n return roles.some((role) => session.roles.includes(role));\r\n}\r\n\r\n/**\r\n * Check if a session has all of the specified roles\r\n */\r\nexport function hasAllRoles(\r\n session: AuthXSession | null | undefined,\r\n roles: string[],\r\n): boolean {\r\n if (\r\n !session ||\r\n !session.roles ||\r\n !Array.isArray(roles) ||\r\n roles.length === 0\r\n ) {\r\n return false;\r\n }\r\n return roles.every((role) => session.roles.includes(role));\r\n}\r\n\r\n/**\r\n * Check if a session has a specific permission\r\n */\r\nexport function hasPermission(\r\n session: AuthXSession | null | undefined,\r\n permission: string,\r\n): boolean {\r\n if (!session || !session.permissions) return false;\r\n return session.permissions.includes(permission);\r\n}\r\n\r\n/**\r\n * Check if a session has any of the specified permissions\r\n */\r\nexport function hasAnyPermission(\r\n session: AuthXSession | null | undefined,\r\n permissions: string[],\r\n): boolean {\r\n if (\r\n !session ||\r\n !session.permissions ||\r\n !Array.isArray(permissions) ||\r\n permissions.length === 0\r\n ) {\r\n return false;\r\n }\r\n return permissions.some((perm) => session.permissions.includes(perm));\r\n}\r\n\r\n/**\r\n * Check if a session has all of the specified permissions\r\n */\r\nexport function hasAllPermissions(\r\n session: AuthXSession | null | undefined,\r\n permissions: string[],\r\n): boolean {\r\n if (\r\n !session ||\r\n !session.permissions ||\r\n !Array.isArray(permissions) ||\r\n permissions.length === 0\r\n ) {\r\n return false;\r\n }\r\n return permissions.every((perm) => session.permissions.includes(perm));\r\n}\r\n","import type { AuthXSession } from 'aaspai-types';\r\nimport type { NextFunction, Request, Response } from 'express';\r\nimport { hasAnyRole } from '../core/utils.js';\r\n\r\n/**\r\n * Express middleware to require one or more roles\r\n * @param roles - Array of role names (user must have at least one)\r\n */\r\nexport function requireRole(...roles: string[]) {\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n const user = (req as any).user as AuthXSession | undefined;\r\n\r\n if (!user) {\r\n return res.status(401).json({ error: 'Unauthorized' });\r\n }\r\n\r\n if (!roles || roles.length === 0) {\r\n return next();\r\n }\r\n\r\n if (!hasAnyRole(user, roles)) {\r\n return res.status(403).json({\r\n error: `Requires one of roles: ${roles.join(', ')}`,\r\n required: roles,\r\n userRoles: user.roles,\r\n });\r\n }\r\n\r\n next();\r\n };\r\n}\r\n","import mongoose, { Document, Schema } from 'mongoose';\r\n\r\nexport interface PermissionsDocument extends Document {\r\n id: string; // stable UUID\r\n orgId?: string | null; // null => platform/global\r\n key: string; // permission key, e.g. \"users.read\"\r\n type: string; // \"GET\", \"POST\", ...\r\n apiId?: string; // \"/api/users\"\r\n description?: string;\r\n isInternal: boolean; // internal vs external\r\n createdAt: Date;\r\n updatedAt: Date;\r\n}\r\n\r\nconst PermissionsSchema = new Schema<PermissionsDocument>(\r\n {\r\n id: { type: String, required: true, index: true },\r\n orgId: { type: String, default: null, index: true },\r\n key: { type: String, required: true },\r\n type: { type: String, required: true },\r\n apiId: { type: String, required: false },\r\n description: { type: String },\r\n isInternal: { type: Boolean, default: false },\r\n },\r\n {\r\n timestamps: true,\r\n },\r\n);\r\n\r\n// One permission key per org\r\nPermissionsSchema.index({ orgId: 1, key: 1 }, { unique: true });\r\n\r\nexport const PermissionsModel = mongoose.model<PermissionsDocument>(\r\n 'Permissions',\r\n PermissionsSchema,\r\n 'permissions',\r\n);\r\n","import type { INestApplication } from '@nestjs/common';\nimport { Db } from 'mongodb';\nimport {\n createAdminRouter,\n createAuthRouter,\n createDashboardRouter,\n createEmailRouter,\n createProjectsRouter,\n} from '../express';\nimport type { AuthRouterOptions } from 'aaspai-types';\n\nexport interface NestAuthxOptions {\n routerOptions?: AuthRouterOptions;\n adminDb?: Db;\n adminBasePath?: string;\n authBasePath?: string;\n dashboardBasePath?: string;\n dnsBasePath?: string;\n emailBasePath?: string;\n uploadBasePath?: string;\n projectsBasePath?: string;\n}\n\nexport const nest = {\n mountAuthRouter(\n app: INestApplication,\n options: NestAuthxOptions,\n ): {\n authRouter: any;\n dashboardRouter?: any;\n dnsRouter?: any;\n emailRouter?: any;\n uploadRouter?: any;\n projectsRouter?: any;\n adminRouter?: any;\n } {\n const httpAdapter = app.getHttpAdapter().getInstance();\n\n const authRouter = createAuthRouter(options.routerOptions || {});\n const authPath = options.authBasePath || '/auth';\n httpAdapter.use(authPath, authRouter);\n\n const adminRouter = createAdminRouter(options);\n const adminPath = options.adminBasePath || '/admin';\n httpAdapter.use(adminPath, adminRouter);\n\n const dashboardRouter = createDashboardRouter(options);\n const dashboardPath = options.dashboardBasePath || '/dashboards';\n httpAdapter.use(dashboardPath, dashboardRouter);\n\n const emailRouter = createEmailRouter(options);\n const emailPath = options.emailBasePath || '/email';\n httpAdapter.use(emailPath, emailRouter);\n\n const projectsRouter = createProjectsRouter(options);\n const projectsPath = options.projectsBasePath || '/projects';\n httpAdapter.use(projectsPath, projectsRouter);\n\n return {\n authRouter,\n dashboardRouter,\n emailRouter,\n projectsRouter,\n adminRouter,\n };\n },\n};\n","// src/middlewares/permission.middleware.ts\r\nimport type { AuthXUser } from 'aaspai-types';\r\nimport { NextFunction, Request, Response } from 'express';\r\nimport { RolePermissionModel } from '../models/rolePermission.model';\r\n\r\ninterface AuthenticatedRequest extends Request {\r\n user?: AuthXUser;\r\n}\r\n\r\nexport function requirePermission(permissionKey: string) {\r\n return async (\r\n req: AuthenticatedRequest,\r\n res: Response,\r\n next: NextFunction,\r\n ) => {\r\n try {\r\n console.log('INSIDE PERMISSION MIDDLEWARE', permissionKey);\r\n const user = req.user;\r\n\r\n if (!user) {\r\n return res.status(401).json({ error: 'Unauthorized' });\r\n }\r\n\r\n const roles = Array.isArray(user.roles) ? user.roles : [];\r\n\r\n if (!roles.length) {\r\n return res.status(403).json({ error: 'Forbidden', reason: 'NO_ROLES' });\r\n }\r\n\r\n // Global superuser shortcut\r\n if (roles.includes('platform_admin')) {\r\n return next();\r\n }\r\n\r\n // Try to determine org context (you can refine this later)\r\n const orgId =\r\n (user.orgId as string) ||\r\n (user.org_id as string) ||\r\n (user.projectId as string) ||\r\n null;\r\n\r\n const rolePermissions = await RolePermissionModel.find({\r\n orgId,\r\n role: { $in: roles },\r\n })\r\n .lean()\r\n .exec();\r\n\r\n const allowed = new Set<string>();\r\n\r\n for (const rp of rolePermissions) {\r\n if (Array.isArray(rp.permissions)) {\r\n for (const p of rp.permissions) {\r\n allowed.add(p);\r\n }\r\n }\r\n }\r\n\r\n if (!allowed.has(permissionKey)) {\r\n return res.status(403).json({\r\n error: 'Forbidden',\r\n reason: 'MISSING_PERMISSION',\r\n permission: permissionKey,\r\n });\r\n }\r\n\r\n return next();\r\n } catch (err) {\r\n return next(err);\r\n }\r\n };\r\n}\r\n","import type { NextFunction, Request, Response } from 'express';\r\nimport { hasPermission } from '../core/utils.js';\r\nimport type { AuthXSession } from 'aaspai-types';\r\n\r\n/**\r\n * Express middleware to require a specific permission\r\n * @param permission - Permission string (e.g., 'projects.create')\r\n */\r\nexport function requirePermission(permission: string) {\r\n return (req: Request, res: Response, next: NextFunction) => {\r\n const user = (req as any).user as AuthXSession | undefined;\r\n\r\n if (!user) {\r\n return res.status(401).json({ error: 'Unauthorized' });\r\n }\r\n\r\n if (!permission) {\r\n return next();\r\n }\r\n\r\n if (!hasPermission(user, permission)) {\r\n return res.status(403).json({\r\n error: 'Forbidden',\r\n reason: 'MISSING_PERMISSION',\r\n permission,\r\n userPermissions: user.permissions,\r\n });\r\n }\r\n\r\n next();\r\n };\r\n}\r\n\r\n","import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';\nimport { randomUUID } from 'crypto';\nimport { config } from '../config/index.js';\n\nexport class UploadsService {\n private s3: S3Client;\n\n constructor() {\n this.s3 = new S3Client({\n region: process.env.AWS_REGION!,\n credentials: {\n accessKeyId: process.env.AWS_ACCESS_KEY_ID!,\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,\n },\n });\n }\n\n async uploadPublicImage(buffer: Buffer, mimetype: string, ext: string) {\n const key = `${randomUUID()}.${ext}`;\n await this.s3.send(\n new PutObjectCommand({\n Bucket: process.env.AWS_S3_BUCKET!,\n Key: key,\n Body: buffer,\n ACL: 'public-read',\n ContentType: mimetype,\n }),\n );\n return `https://${process.env.AWS_S3_BUCKET!}.s3.${process.env.AWS_REGION!}.amazonaws.com/${key}`;\n }\n}\n","import {\r\n ExecutionContext,\r\n ForbiddenException,\r\n Injectable,\r\n UnauthorizedException,\r\n} from '@nestjs/common';\r\nimport { Reflector } from '@nestjs/core';\r\nimport { AuthGuard } from '@nestjs/passport';\r\nimport type { AuthXSession } from 'aaspai-types';\r\nimport { hasAnyPermission, hasAnyRole } from '../core/utils.js';\r\nimport { PERMISSIONS_KEY } from './decorators/permissions.decorator.js';\r\nimport { ROLES_KEY } from './decorators/roles.decorator.js';\r\n\r\n/**\r\n * AuthX Guard for NestJS\r\n * Extends Passport's AuthGuard to authenticate requests using AuthXStrategy,\r\n * then validates role/permission requirements\r\n */\r\n@Injectable()\r\nexport class AuthXGuard extends AuthGuard('authx') {\r\n private readonly reflector = new Reflector();\r\n\r\n constructor() {\r\n super();\r\n }\r\n\r\n /**\r\n * Override handleRequest to convert Passport errors to NestJS exceptions\r\n * This prevents the \"Right-hand side of 'instanceof' is not an object\" error\r\n */\r\n handleRequest(err: any, user: any, info: any, context: any): any {\r\n // If there's an error or no user, throw UnauthorizedException\r\n if (err || !user) {\r\n const message =\r\n err?.message || info?.message || 'Authentication required';\r\n throw new UnauthorizedException(message);\r\n }\r\n return user;\r\n }\r\n\r\n async canActivate(context: ExecutionContext): Promise<boolean> {\r\n try {\r\n // First, trigger Passport authentication (this will set request.user via AuthXStrategy)\r\n // Wrap in try-catch to handle any errors from Passport\r\n let authenticated: boolean;\r\n try {\r\n authenticated = (await super.canActivate(context)) as boolean;\r\n } catch (passportError: any) {\r\n // Convert any Passport errors to UnauthorizedException\r\n const message = passportError?.message || 'Authentication required';\r\n throw new UnauthorizedException(message);\r\n }\r\n\r\n if (!authenticated) {\r\n throw new UnauthorizedException('Authentication required');\r\n }\r\n\r\n const request = context.switchToHttp().getRequest();\r\n const user = (request as any).user as AuthXSession | undefined;\r\n\r\n // Check if user is authenticated (should be set by Passport at this point)\r\n if (!user) {\r\n throw new UnauthorizedException('Authentication required');\r\n }\r\n\r\n // Get required roles from metadata\r\n const requiredRoles = this.reflector.getAllAndOverride<string[]>(\r\n ROLES_KEY,\r\n [context.getHandler(), context.getClass()],\r\n );\r\n \r\n // Get required permissions from metadata\r\n const requiredPermissions = this.reflector.getAllAndOverride<string[]>(\r\n PERMISSIONS_KEY,\r\n [context.getHandler(), context.getClass()],\r\n );\r\n\r\n // Check roles if specified\r\n if (requiredRoles && requiredRoles.length > 0) {\r\n if (!hasAnyRole(user, requiredRoles)) {\r\n throw new ForbiddenException(\r\n `Requires one of roles: ${requiredRoles.join(', ')}`,\r\n );\r\n }\r\n }\r\n\r\n // Check permissions if specified\r\n if (requiredPermissions && requiredPermissions.length > 0) {\r\n if (!hasAnyPermission(user, requiredPermissions)) {\r\n throw new ForbiddenException(\r\n `Requires one of permissions: ${requiredPermissions.join(', ')}`,\r\n );\r\n }\r\n }\r\n\r\n return true;\r\n } catch (error) {\r\n // If it's already a NestJS exception, rethrow it\r\n if (\r\n error instanceof UnauthorizedException ||\r\n error instanceof ForbiddenException\r\n ) {\r\n throw error;\r\n }\r\n // Otherwise, wrap it in UnauthorizedException\r\n const errorMessage =\r\n error instanceof Error ? error.message : String(error);\r\n throw new UnauthorizedException(errorMessage || 'Authentication failed');\r\n }\r\n }\r\n}\r\n","import { SetMetadata } from '@nestjs/common';\r\n\r\nexport const PERMISSIONS_KEY = 'permissions';\r\n\r\n/**\r\n * Decorator to specify required permissions for a route handler or controller\r\n * @param permissions - Array of permission strings (user must have at least one)\r\n */\r\nexport const Permissions = (...permissions: string[]) =>\r\n SetMetadata(PERMISSIONS_KEY, permissions);\r\n\r\n","import { SetMetadata } from '@nestjs/common';\r\n\r\nexport const ROLES_KEY = 'roles';\r\n\r\n/**\r\n * Decorator to specify required roles for a route handler or controller\r\n * @param roles - Array of role names (user must have at least one)\r\n */\r\nexport const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);\r\n\r\n","import { createParamDecorator, ExecutionContext } from '@nestjs/common';\r\nimport type { AuthXSession } from 'aaspai-types';\r\n\r\n/**\r\n * Decorator to inject the AuthXSession into a route handler parameter\r\n * Usage: @AuthXSessionDecorator() session: AuthXSession\r\n */\r\nexport const AuthXSessionDecorator = createParamDecorator(\r\n (data: unknown, ctx: ExecutionContext): AuthXSession | null => {\r\n const request = ctx.switchToHttp().getRequest();\r\n return (request as any).user || null;\r\n },\r\n);\r\n","import type { Request } from 'express';\r\nimport { Strategy } from 'passport';\r\nimport { OrgUser } from '../models/user.model.js';\r\nimport { buildSession } from '../core/session.js';\r\nimport { extractToken } from '../utils/extract.js';\r\nimport { verifyJwt } from '../utils/jwt.js';\r\n\r\n/**\r\n * AuthX Passport Strategy\r\n * Custom Passport strategy that validates JWT tokens using JWKS\r\n * and builds AuthXSession\r\n */\r\nexport class AuthXStrategy extends Strategy {\r\n name = 'authx';\r\n\r\n async authenticate(req: Request) {\r\n try {\r\n const apiKey = req.headers['x-api-key'] as string | undefined;\r\n const userId = req.headers['x-user-id'] as string | undefined;\r\n\r\n if (apiKey) {\r\n if (apiKey !== process.env.SERVER_API_KEY) {\r\n return this.fail({ message: 'Invalid API key' }, 401);\r\n }\r\n if (!userId) {\r\n return this.fail({ message: 'User Id is required' }, 401);\r\n }\r\n\r\n const user = await OrgUser.findOne({\r\n id: userId,\r\n orgId: process.env.ORG_ID || null,\r\n });\r\n\r\n if (!user) {\r\n return this.fail({ message: 'User not found' }, 401);\r\n }\r\n\r\n // Build a synthetic session\r\n const session = buildSession(user);\r\n\r\n // Attach to request\r\n (req as any).user = session;\r\n\r\n return this.success(session);\r\n } else {\r\n \r\n // Extract token from request using existing utility\r\n const token = extractToken(req);\r\n\r\n if (!token) {\r\n return this.fail({ message: 'Missing token' }, 401);\r\n }\r\n\r\n // Verify JWT asynchronously\r\n verifyJwt(token)\r\n .then((claims) => {\r\n // Build canonical session\r\n const session = buildSession(claims);\r\n\r\n // Attach to request\r\n (req as any).user = session;\r\n\r\n // Success\r\n return this.success(session);\r\n })\r\n .catch((error: any) => {\r\n // Verification failed\r\n return this.fail(\r\n { message: error?.message || 'Unauthorized' },\r\n 401,\r\n );\r\n });\r\n }\r\n } catch (error: any) {\r\n return this.fail({ message: error?.message || 'Unauthorized' }, 401);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create AuthXStrategy instance\r\n */\r\nexport function createAuthXStrategy() {\r\n return new AuthXStrategy();\r\n}\r\n"],"mappings":"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","names":["requirePermission","import_jsonwebtoken","mongoose","import_mongoose","mongoose","uuid","parseCookie","jwt","import_mongoose","mongoose","import_jsonwebtoken","import_mongoose","mongoose","bcrypt","jwt","import_jsonwebtoken","nodemailer","jwt","express","bcrypt","jwt","import_express","express","import_express","import_express","import_crypto","import_mongoose","mongoose","import_mongoose","mongoose","import_bcryptjs","import_crypto","import_express","import_mongoose","mongoose","express","bcrypt","requirePermission","import_crypto","import_common","import_common","import_common","import_passport"]}