nucleus-core-ts 0.9.142 → 0.9.145
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.
package/dist/index.js
CHANGED
|
@@ -479,7 +479,7 @@ ${strMDSAlgs}`)}if(attestationStatementAlg!==void 0&&authenticatorGetInfo?.algor
|
|
|
479
479
|
</table>
|
|
480
480
|
</td></tr>
|
|
481
481
|
</table>
|
|
482
|
-
</body></html>`};return sessionsRoutes.get(`${baseRoute}/approve-page`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col8}=getSessionsForRequest(ctx.request);if(!db)return new Response("Service unavailable",{status:503});let token=new URL(ctx.request.url).searchParams.get("token");if(!token){let html2=buildApprovalPageHtml({},"approve","","invalid");return new Response(html2,{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}})}let sessions=await db.select().from(sessionsTable2).where(eq41(col8("approvalToken"),token)).limit(1);if(sessions.length===0){let html2=buildApprovalPageHtml({},"approve",token,"invalid");return new Response(html2,{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}})}let session=sessions[0];if(session.approvalStatus!=="pending"&&session.approval_status!=="pending"){let html2=buildApprovalPageHtml(session,"approve",token,"already_processed");return new Response(html2,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt&&Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS){let html2=buildApprovalPageHtml(session,"approve",token,"expired");return new Response(html2,{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}})}let html=buildApprovalPageHtml(session,"approve",token,"pending");return new Response(html,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})},{detail:{tags:["Authentication"],summary:"Approval page",description:"Standalone HTML page for approving a device (no frontend auth required)"}}),sessionsRoutes.get(`${baseRoute}/reject-page`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col8}=getSessionsForRequest(ctx.request);if(!db)return new Response("Service unavailable",{status:503});let token=new URL(ctx.request.url).searchParams.get("token");if(!token){let html2=buildApprovalPageHtml({},"reject","","invalid");return new Response(html2,{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}})}let sessions=await db.select().from(sessionsTable2).where(eq41(col8("approvalToken"),token)).limit(1);if(sessions.length===0){let html2=buildApprovalPageHtml({},"reject",token,"invalid");return new Response(html2,{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}})}let session=sessions[0];if(session.approvalStatus!=="pending"&&session.approval_status!=="pending"){let html2=buildApprovalPageHtml(session,"reject",token,"already_processed");return new Response(html2,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt&&Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS){let html2=buildApprovalPageHtml(session,"reject",token,"expired");return new Response(html2,{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}})}let html=buildApprovalPageHtml(session,"reject",token,"pending");return new Response(html,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})},{detail:{tags:["Authentication"],summary:"Rejection page",description:"Standalone HTML page for rejecting a device (no frontend auth required)"}}),sessionsRoutes.get(`${baseRoute}/approval-status`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col8}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let sessionId=new URL(ctx.request.url).searchParams.get("sessionId");if(!sessionId)return{success:!1,message:"sessionId is required"};let sessions=await db.select().from(sessionsTable2).where(eq41(col8("id"),sessionId)).limit(1);if(sessions.length===0)return{success:!1,message:"Session not found"};let session=sessions[0];return{success:!0,data:{approvalStatus:session.approvalStatus||session.approval_status||"unknown",isActive:session.isActive||session.is_active}}},{detail:{tags:["Authentication"],summary:"Check approval status",description:"Check the approval status of a pending session"}}),sessionsRoutes}var init_sessions=__esm(()=>{init_scopes();init_types20();init_utils10();init_types20()});function resolveCookies(cookieConfig){return{accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||2592000,secure:cookieConfig?.secure??!0,httpOnly:cookieConfig?.httpOnly??!0,sameSite:cookieConfig?.sameSite||"lax",path:cookieConfig?.path||"/",domain:cookieConfig?.domain}}function buildCookieHeaders(cookies,tokens){let securePart=cookies.secure?"; Secure":"",domainPart=cookies.domain?`; Domain=${cookies.domain}`:"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}${domainPart}`,headers=new Headers;return headers.set("Content-Type","application/json"),headers.set("x-session-id",tokens.sessionId),headers.append("Set-Cookie",`${cookies.accessTokenName}=${tokens.accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`),headers.append("Set-Cookie",`${cookies.refreshTokenName}=${tokens.refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`),headers.append("Set-Cookie",`${cookies.sessionTokenName}=${tokens.sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`),headers}var WebAuthnRegisterOptionsSchema,WebAuthnRegisterVerifySchema,WebAuthnAuthOptionsSchema,WebAuthnAuthVerifySchema,WebAuthnRenameSchema;var init_types21=__esm(()=>{init_esm3();WebAuthnRegisterOptionsSchema=Type.Object({nickname:Type.Optional(Type.String({maxLength:128}))}),WebAuthnRegisterVerifySchema=Type.Object({response:Type.Any(),challenge:Type.String(),nickname:Type.Optional(Type.String({maxLength:128}))}),WebAuthnAuthOptionsSchema=Type.Object({email:Type.Optional(Type.String({format:"email"}))}),WebAuthnAuthVerifySchema=Type.Object({response:Type.Any(),challenge:Type.String(),rememberMe:Type.Optional(Type.Boolean())}),WebAuthnRenameSchema=Type.Object({nickname:Type.String({minLength:1,maxLength:128})})});import{eq as eq42}from"drizzle-orm";import{Elysia as Elysia33}from"elysia";function getSchema(ctx){return ctx.request.headers.get("x-tenant-schema")||void 0}function getUserId(ctx){return ctx.request.headers.get("x-user-id")}function createWebAuthnRoute(config,routeOptions,webauthnService,helpers3,cookieConfig){let{db,logger:logger2}=config,basePath=routeOptions.basePath||"/auth/webauthn",cookies=resolveCookies(cookieConfig),app=new Elysia33;if(!routeOptions.enabled)return app;return app.post(`${basePath}/register/options`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let user=(await db.select().from(usersTable).where(eq42(usersTable.id,userId)).limit(1))[0];if(!user)return ctx.set.status=404,{success:!1,message:"User not found"};return{success:!0,data:await webauthnService.createRegistrationOptions({userId,userName:user.email||userId,userDisplayName:user.email||userId,schemaName:getSchema(ctx)})}},{body:WebAuthnRegisterOptionsSchema}),app.post(`${basePath}/register/verify`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let body=ctx.body,credential=await webauthnService.verifyRegistration({response:body.response,expectedChallenge:body.challenge,userId,nickname:body.nickname,schemaName:getSchema(ctx)});if(!credential)return logger2.warn("[WEBAUTHN] Registration verification failed",{userId}),{success:!1,message:"Registration failed"};return{success:!0,data:{id:credential.id,credentialId:credential.credentialId,nickname:credential.nickname,deviceType:credential.deviceType,backedUp:credential.backedUp,authenticatorAttachment:credential.authenticatorAttachment,aaguid:credential.aaguid,transports:credential.transports,lastUsedAt:credential.lastUsedAt,revokedAt:credential.revokedAt,createdAt:credential.createdAt}}},{body:WebAuthnRegisterVerifySchema}),app.post(`${basePath}/authenticate/options`,async(ctx)=>{let body=ctx.body,resolvedUserId;if(body.email){let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(db&&usersTable){let user=(await db.select().from(usersTable).where(eq42(usersTable.email,body.email.toLowerCase())).limit(1))[0];if(user)resolvedUserId=user.id}}return{success:!0,data:await webauthnService.createAuthenticationOptions({userId:resolvedUserId,schemaName:getSchema(ctx)})}},{body:WebAuthnAuthOptionsSchema}),app.post(`${basePath}/authenticate/verify`,async(ctx)=>{let body=ctx.body,result=await webauthnService.verifyAuthentication({response:body.response,expectedChallenge:body.challenge,schemaName:getSchema(ctx)});if(!result.verified||!result.userId)return ctx.set.status=401,{success:!1,message:"Authentication failed"};let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let user=(await db.select().from(usersTable).where(eq42(usersTable.id,result.userId)).limit(1))[0];if(!user)return ctx.set.status=401,{success:!1,message:"User not found"};let roles=[],claims=[];try{let resolved=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(db,result.userId,resolved);roles=rc.roles,claims=rc.claims}catch{}let accessToken=helpers3.signAccessToken(result.userId,roles.length>0?roles:void 0,claims.length>0?claims:void 0),refreshToken=helpers3.signRefreshToken(result.userId),ipAddress=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",userAgent=ctx.request.headers.get("user-agent")||"",sessionParams={userId:result.userId,deviceInfo:{ipAddress,userAgent,deviceType:"unknown"},loginMethod:"webauthn",rememberMe:body.rememberMe??!1},sessionId=await helpers3.createSession(sessionParams);if(helpers3.saveSessionToDb){let saveResult=await helpers3.saveSessionToDb(sessionId,sessionParams,getSchema(ctx));if(saveResult?.requiresApproval)return{success:!1,requiresApproval:!0,sessionId:saveResult.sessionId??sessionId,message:"Login requires approval"}}let headers=buildCookieHeaders(cookies,{accessToken,refreshToken,sessionId});return logger2.info("[WEBAUTHN] Authentication successful",{userId:result.userId,credentialId:result.credentialId}),new Response(JSON.stringify({success:!0,data:{user:{id:user.id,email:user.email},accessToken,refreshToken,sessionId}}),{status:200,headers})},{body:WebAuthnAuthVerifySchema}),app.get(`${basePath}/credentials`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};return{success:!0,data:{credentials:(await webauthnService.listUserCredentials(userId,getSchema(ctx))).map((cred)=>({id:cred.id,credentialId:cred.credentialId,nickname:cred.nickname,deviceType:cred.deviceType,backedUp:cred.backedUp,authenticatorAttachment:cred.authenticatorAttachment,transports:cred.transports,aaguid:cred.aaguid,lastUsedAt:cred.lastUsedAt,revokedAt:cred.revokedAt,createdAt:cred.createdAt}))}}}),app.delete(`${basePath}/credentials/:credentialId`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let{credentialId}=ctx.params;if(!await webauthnService.revokeCredential(credentialId,userId,getSchema(ctx)))return ctx.set.status=404,{success:!1,message:"Credential not found"};return{success:!0,message:"Credential revoked"}}),app.patch(`${basePath}/credentials/:credentialId`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let{credentialId}=ctx.params,body=ctx.body;if(!await webauthnService.renameCredential(credentialId,userId,body.nickname,getSchema(ctx)))return ctx.set.status=404,{success:!1,message:"Credential not found"};return{success:!0,message:"Credential renamed"}},{body:WebAuthnRenameSchema}),app}var init_webauthn=__esm(()=>{init_fetchUserRolesAndClaims();init_types21();init_types21()});var exports_auth={};__export(exports_auth,{createWebAuthnRoute:()=>createWebAuthnRoute,createSessionsRoute:()=>createSessionsRoute,createRegisterRoute:()=>createRegisterRoute,createRefreshRoute:()=>createRefreshRoute,createPasswordSetRoute:()=>createPasswordSetRoute,createPasswordResetRoute:()=>createPasswordResetRoute,createPasswordChangeRoute:()=>createPasswordChangeRoute,createMeRoute:()=>createMeRoute,createMagicLinkRoute:()=>createMagicLinkRoute,createLogoutRoute:()=>createLogoutRoute,createLoginRoute:()=>createLoginRoute,createInviteRoute:()=>createInviteRoute,createImpersonateRoute:()=>createImpersonateRoute,createHardDeleteUserRoute:()=>createHardDeleteUserRoute,createEmailVerificationRoutes:()=>createEmailVerificationRoutes,createCreateUserRoute:()=>createCreateUserRoute,createChangeUserIdRoute:()=>createChangeUserIdRoute,createAuthRoutes:()=>createAuthRoutes,createApiKeyRoutes:()=>createApiKeyRoutes});function createAuthRoutes(app,config){let{authConfig,features,helpers:helpers3}=config;if(config.oauthAccountsTable)authConfig.oauthAccountsTable=config.oauthAccountsTable;if(config.schemaTables)authConfig.schemaTables=config.schemaTables;if(config.tenantRegistry)authConfig.tenantRegistry=config.tenantRegistry;let buffer=authConfig.authentication?.cookieMaxAgeBufferSeconds??0,rawCookieDomain=authConfig.authentication?.cookieDomain,resolvedCookieDomainRaw=rawCookieDomain?process.env[rawCookieDomain]??rawCookieDomain:void 0,resolvedCookieDomain=resolvedCookieDomainRaw==="localhost"||resolvedCookieDomainRaw===".localhost"?void 0:resolvedCookieDomainRaw,isLocalDev=!resolvedCookieDomain,cookieConfig={accessTokenName:authConfig.authentication?.accessToken?.name||"access_token",refreshTokenName:authConfig.authentication?.refreshToken?.name||"refresh_token",sessionTokenName:authConfig.authentication?.sessionToken?.name||"session_token",accessTokenMaxAge:Math.max(0,parseTimeToSeconds2(authConfig.authentication?.accessToken?.expiresIn||"15m")-buffer),refreshTokenMaxAge:parseTimeToSeconds2(authConfig.authentication?.refreshToken?.expiresIn||"7d"),sessionTokenMaxAge:parseTimeToSeconds2(authConfig.authentication?.sessionToken?.expiresIn||"30d"),domain:resolvedCookieDomain,secure:!isLocalDev,httpOnly:!0,sameSite:"lax",path:"/"};if(authConfig.logger.info("[AUTH] Cookie config created",{accessTokenMaxAge:cookieConfig.accessTokenMaxAge,refreshTokenMaxAge:cookieConfig.refreshTokenMaxAge,sessionTokenMaxAge:cookieConfig.sessionTokenMaxAge,accessTokenExpiresIn:authConfig.authentication?.accessToken?.expiresIn,sessionTokenExpiresIn:authConfig.authentication?.sessionToken?.expiresIn}),features.login?.enabled){let loginRoutes=createLoginRoute(authConfig,features.login,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig,config.tokenResponseConfig);app.use(loginRoutes)}if(features.register?.enabled){let registerRoutes=createRegisterRoute(authConfig,features.register,helpers3.sendWelcomeEmail,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,cookieConfig,config.tokenResponseConfig,config.emailService,config.appName,helpers3.saveSessionToDb);if(app.use(registerRoutes),features.register.emailVerification?.enabled){let emailVerificationRoutes=createEmailVerificationRoutes({authConfig,registerConfig:features.register,emailService:config.emailService,appName:config.appName});app.use(emailVerificationRoutes)}}if(features.logout?.enabled){let logoutRoutes=createLogoutRoute(authConfig,features.logout,helpers3.destroySession,helpers3.revokeSessionInDb,cookieConfig);app.use(logoutRoutes)}if(features.refresh?.enabled){let refreshRoutes=createRefreshRoute(authConfig,features.refresh,helpers3.verifyRefreshToken,helpers3.signAccessToken,helpers3.signRefreshToken,config.tokenResponseConfig,buffer,cookieConfig);app.use(refreshRoutes)}if(features.passwordReset?.enabled&&helpers3.storeResetToken&&helpers3.getResetToken&&helpers3.deleteResetToken){let passwordResetRoutes=createPasswordResetRoute(authConfig,features.passwordReset,helpers3.storeResetToken,helpers3.getResetToken,helpers3.deleteResetToken,helpers3.sendResetEmail);app.use(passwordResetRoutes)}if(features.passwordChange?.enabled){let passwordChangeRoutes=createPasswordChangeRoute(authConfig,features.passwordChange);app.use(passwordChangeRoutes)}if(features.passwordSet?.enabled){let passwordSetRoutes=createPasswordSetRoute(authConfig,features.passwordSet,helpers3.getMagicToken,helpers3.deleteMagicToken);app.use(passwordSetRoutes)}if(features.sessions?.enabled&&config.sessionsTable){let sessionsRoutes=createSessionsRoute(authConfig,features.sessions,config.sessionsTable);app.use(sessionsRoutes)}if(features.magicLink?.enabled&&config.emailService?.isAvailable()&&helpers3.storeMagicToken&&helpers3.getMagicToken&&helpers3.deleteMagicToken){let magicLinkRoutes=createMagicLinkRoute(authConfig,features.magicLink,config.emailService,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.storeMagicToken,helpers3.getMagicToken,helpers3.deleteMagicToken,config.appName,cookieConfig,helpers3.saveSessionToDb);app.use(magicLinkRoutes)}if(features.me?.enabled){let meRoutes=createMeRoute(authConfig,features.me,config.schemaTables||{},config.schemaRelations||{},config.databaseUrl);app.use(meRoutes)}if(features.invite?.enabled&&config.emailService?.isAvailable()&&helpers3.storeMagicToken){let inviteRoutes=createInviteRoute(authConfig,features.invite,config.emailService,helpers3.storeMagicToken,config.appName,helpers3.getMagicToken);app.use(inviteRoutes)}if(features.captcha?.enabled&&config.captchaService){let captchaRoutes=createCaptchaRoutes({captchaService:config.captchaService,logger:authConfig.logger,basePath:features.captcha.route||"/auth/captcha"});app.use(captchaRoutes)}if(features.oauth?.enabled&&features.oauth.providers){let oauthService=new OAuthService(features.oauth),oauthRoutes=createOAuthRoutes(authConfig,oauthService,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig,config.tokenResponseConfig,config.emailService,helpers3.storeMagicToken,config.appName);app.use(oauthRoutes)}if(features.apiKeys?.enabled&&config.apiKeysTable)authConfig.apiKeysTable=config.apiKeysTable,createApiKeyRoutes(app,authConfig,features.apiKeys);if(features.webauthn?.enabled&&config.webauthnService){let webauthnRoutes=createWebAuthnRoute(authConfig,{basePath:features.webauthn.route||"/auth/webauthn",isPublic:features.webauthn.isPublic,enabled:!0},config.webauthnService,{signAccessToken:helpers3.signAccessToken,signRefreshToken:helpers3.signRefreshToken,createSession:helpers3.createSession,saveSessionToDb:helpers3.saveSessionToDb},cookieConfig);app.use(webauthnRoutes)}let checkRoutes=createCheckRoute(authConfig,{route:"/auth/check",isPublic:!1,enabled:!0});if(app.use(checkRoutes),config.admin?.impersonate?.enabled!==!1){let impersonateRoutes=createImpersonateRoute(authConfig,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig);app.use(impersonateRoutes)}if(config.admin?.changeUserId?.enabled!==!1){let changeUserIdRoutes=createChangeUserIdRoute(authConfig,config.schemaName||"public");app.use(changeUserIdRoutes)}if(config.admin?.createUser?.enabled!==!1){let createUserRoutes=createCreateUserRoute(authConfig,config.admin?.createUser);app.use(createUserRoutes)}let hardDeleteRoutes=createHardDeleteUserRoute(authConfig);return app.use(hardDeleteRoutes),app}var init_auth=__esm(()=>{init_OAuth();init_utils5();init_changeUserId();init_createUser();init_hardDeleteUser();init_impersonate();init_apiKeys();init_captcha();init_check();init_emailVerification();init_invite();init_login();init_logout();init_magicLink();init_me();init_oauth();init_passwordChange();init_passwordReset();init_passwordSet();init_refresh();init_register();init_sessions();init_webauthn();init_changeUserId();init_createUser();init_hardDeleteUser();init_impersonate();init_apiKeys();init_emailVerification();init_invite();init_login();init_logout();init_magicLink();init_me();init_passwordChange();init_passwordReset();init_passwordSet();init_refresh();init_register();init_sessions();init_webauthn()});var exports_backup={};__export(exports_backup,{createBackupRoutes:()=>createBackupRoutes});import{Elysia as Elysia34,t as t29}from"elysia";function createBackupRoutes(routeConfig){let{db,logger:logger2,schemaTables,schemaName,tenantRegistry}=routeConfig,config={...DEFAULT_BACKUP_CONFIG,...routeConfig.config},basePath=config.basePath,backupLogsTable=schemaTables.backupLogs||schemaTables.backup_logs,backupService=new BackupService({db,logger:logger2,config,schemaTables,schemaName,backupLogsTable});if(config.schedule.enabled)backupService.startScheduler();let routes=new Elysia34;return routes.post(basePath,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let targetSchema=ctx.body?.schema,targetSchemaTables=schemaTables,targetSchemaName=schemaName;if(targetSchema&&tenantRegistry){let tenantCtx=tenantRegistry.getSchemaContext(targetSchema);if(!tenantCtx)return ctx.set.status=404,{success:!1,message:`Schema not found: ${targetSchema}`};targetSchemaTables=tenantCtx.schemaTables,targetSchemaName=targetSchema}let result=await backupService.createBackup("manual",userId,targetSchemaName,targetSchemaTables);if(result.status==="failed")return ctx.set.status=500,{success:!1,message:result.errorMessage||"Backup failed"};return{success:!0,message:"Backup created successfully",data:{id:result.id,backupName:result.backupName,schemaName:result.schemaName,tableCount:result.tableCount,rowCount:result.rowCount,sizeBytes:result.sizeBytes,status:result.status}}},{body:t29.Optional(t29.Object({schema:t29.Optional(t29.String())})),detail:{tags:["Backup"],summary:"Create backup",description:"Create a new database backup. Optionally specify a schema for multi-tenant backups."}}),routes.get(basePath,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required",data:null};let backups=await backupService.listBackups();return{success:!0,data:{items:backups,totalCount:backups.length}}},{detail:{tags:["Backup"],summary:"List backups",description:"List all backup records."}}),routes.get(`${basePath}/:id/download`,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required"};let{id}=ctx.params,filePath=await backupService.getBackupFilePath(id);if(!filePath)return ctx.set.status=404,{success:!1,message:"Backup not found"};try{let{readFile:readFile2}=await import("fs/promises"),content=await readFile2(filePath,"utf-8");return new Response(content,{headers:{"Content-Type":"application/json","Content-Disposition":`attachment; filename="${id}.json"`}})}catch{return ctx.set.status=404,{success:!1,message:"Backup file not found on disk"}}},{detail:{tags:["Backup"],summary:"Download backup",description:"Download a backup file by ID."}}),routes.post(`${basePath}/:id/restore`,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!config.allowRestore)return ctx.set.status=403,{success:!1,message:"Restore is disabled in configuration"};let{id}=ctx.params,result=await backupService.restoreFromBackup(id,userId);if(!result.success)return ctx.set.status=400,result;return await logger2.audit({entityName:"backup_logs",entityId:id,operation:"RESTORE",userId,summary:`Database restored from backup ${id}`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""}),result},{detail:{tags:["Backup"],summary:"Restore from backup",description:"Restore database from a specific backup. Creates a pre-restore backup automatically."}}),routes.delete(`${basePath}/:id`,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required"};let{id}=ctx.params;if(!await backupService.deleteBackup(id))return ctx.set.status=404,{success:!1,message:"Backup not found"};return{success:!0,message:"Backup deleted"}},{detail:{tags:["Backup"],summary:"Delete backup",description:"Delete a specific backup and its file."}}),{routes,backupService}}var DEFAULT_BACKUP_CONFIG;var init_backup=__esm(()=>{init_Backup();DEFAULT_BACKUP_CONFIG={enabled:!1,basePath:"/admin/backup",storagePath:"./backups",format:"json",maxBackups:50,allowRestore:!0,excludeTables:["audit_logs","backup_logs"],schedule:{enabled:!1,cron:"0 2 * * *",retentionDays:30}}});var exports_payment={};__export(exports_payment,{createPaymentRoutes:()=>createPaymentRoutes});import{Elysia as Elysia35}from"elysia";import{eq as eq43,and as and10}from"drizzle-orm";var generateRedirectHtml=(url,title)=>`
|
|
482
|
+
</body></html>`};return sessionsRoutes.get(`${baseRoute}/approve-page`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col8}=getSessionsForRequest(ctx.request);if(!db)return new Response("Service unavailable",{status:503});let token=new URL(ctx.request.url).searchParams.get("token");if(!token){let html2=buildApprovalPageHtml({},"approve","","invalid");return new Response(html2,{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}})}let sessions=await db.select().from(sessionsTable2).where(eq41(col8("approvalToken"),token)).limit(1);if(sessions.length===0){let html2=buildApprovalPageHtml({},"approve",token,"invalid");return new Response(html2,{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}})}let session=sessions[0];if(session.approvalStatus!=="pending"&&session.approval_status!=="pending"){let html2=buildApprovalPageHtml(session,"approve",token,"already_processed");return new Response(html2,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt&&Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS){let html2=buildApprovalPageHtml(session,"approve",token,"expired");return new Response(html2,{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}})}let html=buildApprovalPageHtml(session,"approve",token,"pending");return new Response(html,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})},{detail:{tags:["Authentication"],summary:"Approval page",description:"Standalone HTML page for approving a device (no frontend auth required)"}}),sessionsRoutes.get(`${baseRoute}/reject-page`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col8}=getSessionsForRequest(ctx.request);if(!db)return new Response("Service unavailable",{status:503});let token=new URL(ctx.request.url).searchParams.get("token");if(!token){let html2=buildApprovalPageHtml({},"reject","","invalid");return new Response(html2,{status:400,headers:{"Content-Type":"text/html; charset=utf-8"}})}let sessions=await db.select().from(sessionsTable2).where(eq41(col8("approvalToken"),token)).limit(1);if(sessions.length===0){let html2=buildApprovalPageHtml({},"reject",token,"invalid");return new Response(html2,{status:404,headers:{"Content-Type":"text/html; charset=utf-8"}})}let session=sessions[0];if(session.approvalStatus!=="pending"&&session.approval_status!=="pending"){let html2=buildApprovalPageHtml(session,"reject",token,"already_processed");return new Response(html2,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})}let requestedAt=session.approvalRequestedAt||session.approval_requested_at;if(requestedAt&&Date.now()-new Date(requestedAt).getTime()>APPROVAL_TOKEN_TTL_MS){let html2=buildApprovalPageHtml(session,"reject",token,"expired");return new Response(html2,{status:410,headers:{"Content-Type":"text/html; charset=utf-8"}})}let html=buildApprovalPageHtml(session,"reject",token,"pending");return new Response(html,{status:200,headers:{"Content-Type":"text/html; charset=utf-8"}})},{detail:{tags:["Authentication"],summary:"Rejection page",description:"Standalone HTML page for rejecting a device (no frontend auth required)"}}),sessionsRoutes.get(`${baseRoute}/approval-status`,async(ctx)=>{let{sessionsTable:sessionsTable2,col:col8}=getSessionsForRequest(ctx.request);if(!db)return{success:!1,message:"Database not configured"};let sessionId=new URL(ctx.request.url).searchParams.get("sessionId");if(!sessionId)return{success:!1,message:"sessionId is required"};let sessions=await db.select().from(sessionsTable2).where(eq41(col8("id"),sessionId)).limit(1);if(sessions.length===0)return{success:!1,message:"Session not found"};let session=sessions[0];return{success:!0,data:{approvalStatus:session.approvalStatus||session.approval_status||"unknown",isActive:session.isActive||session.is_active}}},{detail:{tags:["Authentication"],summary:"Check approval status",description:"Check the approval status of a pending session"}}),sessionsRoutes}var init_sessions=__esm(()=>{init_scopes();init_types20();init_utils10();init_types20()});function resolveCookies(cookieConfig){return{accessTokenName:cookieConfig?.accessTokenName||"access_token",refreshTokenName:cookieConfig?.refreshTokenName||"refresh_token",sessionTokenName:cookieConfig?.sessionTokenName||"session_token",accessTokenMaxAge:cookieConfig?.accessTokenMaxAge||900,refreshTokenMaxAge:cookieConfig?.refreshTokenMaxAge||604800,sessionTokenMaxAge:cookieConfig?.sessionTokenMaxAge||2592000,secure:cookieConfig?.secure??!0,httpOnly:cookieConfig?.httpOnly??!0,sameSite:cookieConfig?.sameSite||"lax",path:cookieConfig?.path||"/",domain:cookieConfig?.domain}}function buildCookieHeaders(cookies,tokens){let securePart=cookies.secure?"; Secure":"",domainPart=cookies.domain?`; Domain=${cookies.domain}`:"",cookieOptions=`; Path=${cookies.path}; HttpOnly; SameSite=${cookies.sameSite}${securePart}${domainPart}`,headers=new Headers;return headers.set("Content-Type","application/json"),headers.set("x-session-id",tokens.sessionId),headers.append("Set-Cookie",`${cookies.accessTokenName}=${tokens.accessToken}${cookieOptions}; Max-Age=${cookies.accessTokenMaxAge}`),headers.append("Set-Cookie",`${cookies.refreshTokenName}=${tokens.refreshToken}${cookieOptions}; Max-Age=${cookies.refreshTokenMaxAge}`),headers.append("Set-Cookie",`${cookies.sessionTokenName}=${tokens.sessionId}${cookieOptions}; Max-Age=${cookies.sessionTokenMaxAge}`),headers}var WebAuthnRegisterOptionsSchema,WebAuthnRegisterVerifySchema,WebAuthnAuthOptionsSchema,WebAuthnAuthVerifySchema,WebAuthnRenameSchema;var init_types21=__esm(()=>{init_esm3();WebAuthnRegisterOptionsSchema=Type.Object({nickname:Type.Optional(Type.String({maxLength:128}))}),WebAuthnRegisterVerifySchema=Type.Object({response:Type.Any(),challenge:Type.String(),nickname:Type.Optional(Type.String({maxLength:128}))}),WebAuthnAuthOptionsSchema=Type.Object({email:Type.Optional(Type.String({format:"email"}))}),WebAuthnAuthVerifySchema=Type.Object({response:Type.Any(),challenge:Type.String(),rememberMe:Type.Optional(Type.Boolean())}),WebAuthnRenameSchema=Type.Object({nickname:Type.String({minLength:1,maxLength:128})})});import{eq as eq42}from"drizzle-orm";import{Elysia as Elysia33}from"elysia";function getSchema(ctx){return ctx.request.headers.get("x-tenant-schema")||void 0}function getUserId(ctx){return ctx.request.headers.get("x-user-id")}function createWebAuthnRoute(config,routeOptions,webauthnService,helpers3,cookieConfig){let{db,logger:logger2}=config,basePath=routeOptions.basePath||"/auth/webauthn",cookies=resolveCookies(cookieConfig),app=new Elysia33;if(!routeOptions.enabled)return app;return app.post(`${basePath}/register/options`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let user=(await db.select().from(usersTable).where(eq42(usersTable.id,userId)).limit(1))[0];if(!user)return ctx.set.status=404,{success:!1,message:"User not found"};return{success:!0,data:await webauthnService.createRegistrationOptions({userId,userName:user.email||userId,userDisplayName:user.email||userId,schemaName:getSchema(ctx)})}},{body:WebAuthnRegisterOptionsSchema}),app.post(`${basePath}/register/verify`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let body=ctx.body,credential=await webauthnService.verifyRegistration({response:body.response,expectedChallenge:body.challenge,userId,nickname:body.nickname,schemaName:getSchema(ctx)});if(!credential)return logger2.warn("[WEBAUTHN] Registration verification failed",{userId}),{success:!1,message:"Registration failed"};return{success:!0,data:{id:credential.id,credentialId:credential.credentialId,nickname:credential.nickname,deviceType:credential.deviceType,backedUp:credential.backedUp,authenticatorAttachment:credential.authenticatorAttachment,aaguid:credential.aaguid,transports:credential.transports,lastUsedAt:credential.lastUsedAt,revokedAt:credential.revokedAt,createdAt:credential.createdAt}}},{body:WebAuthnRegisterVerifySchema}),app.post(`${basePath}/authenticate/options`,async(ctx)=>{let body=ctx.body,resolvedUserId;if(body.email){let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(db&&usersTable){let user=(await db.select().from(usersTable).where(eq42(usersTable.email,body.email.toLowerCase())).limit(1))[0];if(user)resolvedUserId=user.id}}return{success:!0,data:await webauthnService.createAuthenticationOptions({userId:resolvedUserId,schemaName:getSchema(ctx)})}},{body:WebAuthnAuthOptionsSchema}),app.post(`${basePath}/authenticate/verify`,async(ctx)=>{let body=ctx.body,result=await webauthnService.verifyAuthentication({response:body.response,expectedChallenge:body.challenge,schemaName:getSchema(ctx)});if(!result.verified||!result.userId)return ctx.set.status=401,{success:!1,message:"Authentication failed"};let{usersTable}=resolveAuthTablesForRequest(ctx.request,config);if(!db||!usersTable)return{success:!1,message:"Database not configured"};let user=(await db.select().from(usersTable).where(eq42(usersTable.id,result.userId)).limit(1))[0];if(!user)return ctx.set.status=401,{success:!1,message:"User not found"};let roles=[],claims=[];try{let resolved=resolveAuthTablesForRequest(ctx.request,config),rc=await fetchUserRolesAndClaims(db,result.userId,resolved);roles=rc.roles,claims=rc.claims}catch{}let accessToken=helpers3.signAccessToken(result.userId,roles.length>0?roles:void 0,claims.length>0?claims:void 0),refreshToken=helpers3.signRefreshToken(result.userId),ipAddress=ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||ctx.request.headers.get("x-real-ip")?.trim()||"unknown",userAgent=ctx.request.headers.get("user-agent")||"",sessionParams={userId:result.userId,deviceInfo:{ipAddress,userAgent,deviceType:"unknown"},loginMethod:"webauthn",rememberMe:body.rememberMe??!1},sessionId=await helpers3.createSession(sessionParams);if(helpers3.saveSessionToDb){let saveResult=await helpers3.saveSessionToDb(sessionId,sessionParams,getSchema(ctx));if(saveResult?.requiresApproval)return{success:!1,requiresApproval:!0,sessionId:saveResult.sessionId??sessionId,message:"Login requires approval"}}let headers=buildCookieHeaders(cookies,{accessToken,refreshToken,sessionId});return logger2.info("[WEBAUTHN] Authentication successful",{userId:result.userId,credentialId:result.credentialId}),new Response(JSON.stringify({success:!0,data:{user:{id:user.id,email:user.email},accessToken,refreshToken,sessionId}}),{status:200,headers})},{body:WebAuthnAuthVerifySchema}),app.get(`${basePath}/credentials`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};return{success:!0,data:{credentials:(await webauthnService.listUserCredentials(userId,getSchema(ctx))).map((cred)=>({id:cred.id,credentialId:cred.credentialId,nickname:cred.nickname,deviceType:cred.deviceType,backedUp:cred.backedUp,authenticatorAttachment:cred.authenticatorAttachment,transports:cred.transports,aaguid:cred.aaguid,lastUsedAt:cred.lastUsedAt,revokedAt:cred.revokedAt,createdAt:cred.createdAt}))}}}),app.delete(`${basePath}/credentials/:credentialId`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let{credentialId}=ctx.params;if(!await webauthnService.revokeCredential(credentialId,userId,getSchema(ctx)))return ctx.set.status=404,{success:!1,message:"Credential not found"};return{success:!0,message:"Credential revoked"}}),app.patch(`${basePath}/credentials/:credentialId`,async(ctx)=>{let userId=getUserId(ctx);if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let{credentialId}=ctx.params,body=ctx.body;if(!await webauthnService.renameCredential(credentialId,userId,body.nickname,getSchema(ctx)))return ctx.set.status=404,{success:!1,message:"Credential not found"};return{success:!0,message:"Credential renamed"}},{body:WebAuthnRenameSchema}),app}var init_webauthn=__esm(()=>{init_fetchUserRolesAndClaims();init_types21();init_types21()});var exports_auth={};__export(exports_auth,{createWebAuthnRoute:()=>createWebAuthnRoute,createSessionsRoute:()=>createSessionsRoute,createRegisterRoute:()=>createRegisterRoute,createRefreshRoute:()=>createRefreshRoute,createPasswordSetRoute:()=>createPasswordSetRoute,createPasswordResetRoute:()=>createPasswordResetRoute,createPasswordChangeRoute:()=>createPasswordChangeRoute,createMeRoute:()=>createMeRoute,createMagicLinkRoute:()=>createMagicLinkRoute,createLogoutRoute:()=>createLogoutRoute,createLoginRoute:()=>createLoginRoute,createInviteRoute:()=>createInviteRoute,createImpersonateRoute:()=>createImpersonateRoute,createHardDeleteUserRoute:()=>createHardDeleteUserRoute,createEmailVerificationRoutes:()=>createEmailVerificationRoutes,createCreateUserRoute:()=>createCreateUserRoute,createChangeUserIdRoute:()=>createChangeUserIdRoute,createAuthRoutes:()=>createAuthRoutes,createApiKeyRoutes:()=>createApiKeyRoutes});function createAuthRoutes(app,config){let{authConfig,features,helpers:helpers3}=config;if(config.oauthAccountsTable)authConfig.oauthAccountsTable=config.oauthAccountsTable;if(config.schemaTables)authConfig.schemaTables=config.schemaTables;if(config.tenantRegistry)authConfig.tenantRegistry=config.tenantRegistry;let buffer=authConfig.authentication?.cookieMaxAgeBufferSeconds??0,rawCookieDomain=authConfig.authentication?.cookieDomain,resolvedCookieDomainRaw=rawCookieDomain?process.env[rawCookieDomain]??rawCookieDomain:void 0,resolvedCookieDomain=resolvedCookieDomainRaw==="localhost"||resolvedCookieDomainRaw===".localhost"?void 0:resolvedCookieDomainRaw,isLocalDev=!resolvedCookieDomain,cookieConfig={accessTokenName:authConfig.authentication?.accessToken?.name||"access_token",refreshTokenName:authConfig.authentication?.refreshToken?.name||"refresh_token",sessionTokenName:authConfig.authentication?.sessionToken?.name||"session_token",accessTokenMaxAge:Math.max(0,parseTimeToSeconds2(authConfig.authentication?.accessToken?.expiresIn||"15m")-buffer),refreshTokenMaxAge:parseTimeToSeconds2(authConfig.authentication?.refreshToken?.expiresIn||"7d"),sessionTokenMaxAge:parseTimeToSeconds2(authConfig.authentication?.sessionToken?.expiresIn||"30d"),domain:resolvedCookieDomain,secure:!isLocalDev,httpOnly:!0,sameSite:"lax",path:"/"};if(authConfig.logger.info("[AUTH] Cookie config created",{accessTokenMaxAge:cookieConfig.accessTokenMaxAge,refreshTokenMaxAge:cookieConfig.refreshTokenMaxAge,sessionTokenMaxAge:cookieConfig.sessionTokenMaxAge,accessTokenExpiresIn:authConfig.authentication?.accessToken?.expiresIn,sessionTokenExpiresIn:authConfig.authentication?.sessionToken?.expiresIn}),features.login?.enabled){let loginRoutes=createLoginRoute(authConfig,features.login,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig,config.tokenResponseConfig);app.use(loginRoutes)}if(features.register?.enabled){let registerRoutes=createRegisterRoute(authConfig,features.register,helpers3.sendWelcomeEmail,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,cookieConfig,config.tokenResponseConfig,config.emailService,config.appName,helpers3.saveSessionToDb);if(app.use(registerRoutes),features.register.emailVerification?.enabled){let emailVerificationRoutes=createEmailVerificationRoutes({authConfig,registerConfig:features.register,emailService:config.emailService,appName:config.appName});app.use(emailVerificationRoutes)}}if(features.logout?.enabled){let logoutRoutes=createLogoutRoute(authConfig,features.logout,helpers3.destroySession,helpers3.revokeSessionInDb,cookieConfig);app.use(logoutRoutes)}if(features.refresh?.enabled){let refreshRoutes=createRefreshRoute(authConfig,features.refresh,helpers3.verifyRefreshToken,helpers3.signAccessToken,helpers3.signRefreshToken,config.tokenResponseConfig,buffer,cookieConfig);app.use(refreshRoutes)}if(features.passwordReset?.enabled&&helpers3.storeResetToken&&helpers3.getResetToken&&helpers3.deleteResetToken){let passwordResetRoutes=createPasswordResetRoute(authConfig,features.passwordReset,helpers3.storeResetToken,helpers3.getResetToken,helpers3.deleteResetToken,helpers3.sendResetEmail);app.use(passwordResetRoutes)}if(features.passwordChange?.enabled){let passwordChangeRoutes=createPasswordChangeRoute(authConfig,features.passwordChange);app.use(passwordChangeRoutes)}if(features.passwordSet?.enabled){let passwordSetRoutes=createPasswordSetRoute(authConfig,features.passwordSet,helpers3.getMagicToken,helpers3.deleteMagicToken);app.use(passwordSetRoutes)}if(features.sessions?.enabled&&config.sessionsTable){let sessionsRoutes=createSessionsRoute(authConfig,features.sessions,config.sessionsTable);app.use(sessionsRoutes)}if(features.magicLink?.enabled&&config.emailService?.isAvailable()&&helpers3.storeMagicToken&&helpers3.getMagicToken&&helpers3.deleteMagicToken){let magicLinkRoutes=createMagicLinkRoute(authConfig,features.magicLink,config.emailService,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.storeMagicToken,helpers3.getMagicToken,helpers3.deleteMagicToken,config.appName,cookieConfig,helpers3.saveSessionToDb);app.use(magicLinkRoutes)}if(features.me?.enabled){let meRoutes=createMeRoute(authConfig,features.me,config.schemaTables||{},config.schemaRelations||{},config.databaseUrl);app.use(meRoutes)}if(features.invite?.enabled&&config.emailService?.isAvailable()&&helpers3.storeMagicToken){let inviteRoutes=createInviteRoute(authConfig,features.invite,config.emailService,helpers3.storeMagicToken,config.appName,helpers3.getMagicToken);app.use(inviteRoutes)}if(features.captcha?.enabled&&config.captchaService){let captchaRoutes=createCaptchaRoutes({captchaService:config.captchaService,logger:authConfig.logger,basePath:features.captcha.route||"/auth/captcha"});app.use(captchaRoutes)}if(features.oauth?.enabled&&features.oauth.providers){let oauthService=new OAuthService(features.oauth),oauthRoutes=createOAuthRoutes(authConfig,oauthService,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig,config.tokenResponseConfig,config.emailService,helpers3.storeMagicToken,config.appName);app.use(oauthRoutes)}if(features.apiKeys?.enabled&&config.apiKeysTable)authConfig.apiKeysTable=config.apiKeysTable,createApiKeyRoutes(app,authConfig,features.apiKeys);if(features.webauthn?.enabled&&config.webauthnService){let webauthnRoutes=createWebAuthnRoute(authConfig,{basePath:features.webauthn.route||"/auth/webauthn",isPublic:features.webauthn.isPublic,enabled:!0},config.webauthnService,{signAccessToken:helpers3.signAccessToken,signRefreshToken:helpers3.signRefreshToken,createSession:helpers3.createSession,saveSessionToDb:helpers3.saveSessionToDb},cookieConfig);app.use(webauthnRoutes)}let checkRoutes=createCheckRoute(authConfig,{route:"/auth/check",isPublic:!1,enabled:!0});if(app.use(checkRoutes),config.admin?.impersonate?.enabled!==!1){let impersonateRoutes=createImpersonateRoute(authConfig,helpers3.signAccessToken,helpers3.signRefreshToken,helpers3.createSession,helpers3.saveSessionToDb,cookieConfig);app.use(impersonateRoutes)}if(config.admin?.changeUserId?.enabled!==!1){let changeUserIdRoutes=createChangeUserIdRoute(authConfig,config.schemaName||"public");app.use(changeUserIdRoutes)}if(config.admin?.createUser?.enabled!==!1){let createUserRoutes=createCreateUserRoute(authConfig,config.admin?.createUser);app.use(createUserRoutes)}if(config.admin?.hardDelete?.enabled!==!1){let hardDeleteRoutes=createHardDeleteUserRoute(authConfig);app.use(hardDeleteRoutes)}return app}var init_auth=__esm(()=>{init_OAuth();init_utils5();init_changeUserId();init_createUser();init_hardDeleteUser();init_impersonate();init_apiKeys();init_captcha();init_check();init_emailVerification();init_invite();init_login();init_logout();init_magicLink();init_me();init_oauth();init_passwordChange();init_passwordReset();init_passwordSet();init_refresh();init_register();init_sessions();init_webauthn();init_changeUserId();init_createUser();init_hardDeleteUser();init_impersonate();init_apiKeys();init_emailVerification();init_invite();init_login();init_logout();init_magicLink();init_me();init_passwordChange();init_passwordReset();init_passwordSet();init_refresh();init_register();init_sessions();init_webauthn()});var exports_backup={};__export(exports_backup,{createBackupRoutes:()=>createBackupRoutes});import{Elysia as Elysia34,t as t29}from"elysia";function createBackupRoutes(routeConfig){let{db,logger:logger2,schemaTables,schemaName,tenantRegistry}=routeConfig,config={...DEFAULT_BACKUP_CONFIG,...routeConfig.config},basePath=config.basePath,backupLogsTable=schemaTables.backupLogs||schemaTables.backup_logs,backupService=new BackupService({db,logger:logger2,config,schemaTables,schemaName,backupLogsTable});if(config.schedule.enabled)backupService.startScheduler();let routes=new Elysia34;return routes.post(basePath,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};let targetSchema=ctx.body?.schema,targetSchemaTables=schemaTables,targetSchemaName=schemaName;if(targetSchema&&tenantRegistry){let tenantCtx=tenantRegistry.getSchemaContext(targetSchema);if(!tenantCtx)return ctx.set.status=404,{success:!1,message:`Schema not found: ${targetSchema}`};targetSchemaTables=tenantCtx.schemaTables,targetSchemaName=targetSchema}let result=await backupService.createBackup("manual",userId,targetSchemaName,targetSchemaTables);if(result.status==="failed")return ctx.set.status=500,{success:!1,message:result.errorMessage||"Backup failed"};return{success:!0,message:"Backup created successfully",data:{id:result.id,backupName:result.backupName,schemaName:result.schemaName,tableCount:result.tableCount,rowCount:result.rowCount,sizeBytes:result.sizeBytes,status:result.status}}},{body:t29.Optional(t29.Object({schema:t29.Optional(t29.String())})),detail:{tags:["Backup"],summary:"Create backup",description:"Create a new database backup. Optionally specify a schema for multi-tenant backups."}}),routes.get(basePath,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required",data:null};let backups=await backupService.listBackups();return{success:!0,data:{items:backups,totalCount:backups.length}}},{detail:{tags:["Backup"],summary:"List backups",description:"List all backup records."}}),routes.get(`${basePath}/:id/download`,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required"};let{id}=ctx.params,filePath=await backupService.getBackupFilePath(id);if(!filePath)return ctx.set.status=404,{success:!1,message:"Backup not found"};try{let{readFile:readFile2}=await import("fs/promises"),content=await readFile2(filePath,"utf-8");return new Response(content,{headers:{"Content-Type":"application/json","Content-Disposition":`attachment; filename="${id}.json"`}})}catch{return ctx.set.status=404,{success:!1,message:"Backup file not found on disk"}}},{detail:{tags:["Backup"],summary:"Download backup",description:"Download a backup file by ID."}}),routes.post(`${basePath}/:id/restore`,async(ctx)=>{let userId=ctx.request.headers.get("x-user-id");if(!userId)return ctx.set.status=401,{success:!1,message:"Authentication required"};if(!config.allowRestore)return ctx.set.status=403,{success:!1,message:"Restore is disabled in configuration"};let{id}=ctx.params,result=await backupService.restoreFromBackup(id,userId);if(!result.success)return ctx.set.status=400,result;return await logger2.audit({entityName:"backup_logs",entityId:id,operation:"RESTORE",userId,summary:`Database restored from backup ${id}`,ipAddress:ctx.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||"unknown",userAgent:ctx.request.headers.get("user-agent")||"unknown",path:new URL(ctx.request.url).pathname,query:""}),result},{detail:{tags:["Backup"],summary:"Restore from backup",description:"Restore database from a specific backup. Creates a pre-restore backup automatically."}}),routes.delete(`${basePath}/:id`,async(ctx)=>{if(!ctx.request.headers.get("x-user-id"))return ctx.set.status=401,{success:!1,message:"Authentication required"};let{id}=ctx.params;if(!await backupService.deleteBackup(id))return ctx.set.status=404,{success:!1,message:"Backup not found"};return{success:!0,message:"Backup deleted"}},{detail:{tags:["Backup"],summary:"Delete backup",description:"Delete a specific backup and its file."}}),{routes,backupService}}var DEFAULT_BACKUP_CONFIG;var init_backup=__esm(()=>{init_Backup();DEFAULT_BACKUP_CONFIG={enabled:!1,basePath:"/admin/backup",storagePath:"./backups",format:"json",maxBackups:50,allowRestore:!0,excludeTables:["audit_logs","backup_logs"],schedule:{enabled:!1,cron:"0 2 * * *",retentionDays:30}}});var exports_payment={};__export(exports_payment,{createPaymentRoutes:()=>createPaymentRoutes});import{Elysia as Elysia35}from"elysia";import{eq as eq43,and as and10}from"drizzle-orm";var generateRedirectHtml=(url,title)=>`
|
|
483
483
|
<!DOCTYPE html>
|
|
484
484
|
<html>
|
|
485
485
|
<head>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nucleus-core-ts",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.145",
|
|
4
4
|
"description": "Production-ready, enterprise-grade TypeScript framework for building multi-tenant APIs",
|
|
5
5
|
"author": "Hidayet Can Özcan <hidayetcan@gmail.com>",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|