@tern-secure/nextjs 5.2.0-canary.v20251202172616 → 5.2.0-canary.v20251202183844

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.
@@ -141,6 +141,8 @@ const signInEndpointHandler = async (context) => {
141
141
  const response = await backendClient.signIn.resetPasswordEmail(import_constants.FIREBASE_API_KEY, {
142
142
  email,
143
143
  requestType: "PASSWORD_RESET"
144
+ }, {
145
+ appCheckToken: context.appCheckToken
144
146
  });
145
147
  if (!response) {
146
148
  return (0, import_responses.createApiErrorResponse)(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/handlers.ts"],"sourcesContent":["import type { AuthenticateRequestOptions, RequestProcessorContext } from '@tern-secure/backend';\nimport { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { FIREBASE_API_KEY } from './constants';\nimport { refreshCookieWithIdToken } from './request';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n HttpResponseHelper,\n SessionResponseHelper,\n} from './responses';\nimport { processSignInCreate } from './signInCreateHandler';\nimport type { SessionSubEndpoint, SignInSubEndpoint, } from './types';\nimport {\n extractSessionRequestData,\n validateCsrfToken,\n validateEmail,\n validateIdToken,\n validateSubEndpointPresent,\n} from './validators';\n\nconst sessionEndpointHandler = async (\n context: RequestProcessorContext,\n config: AuthenticateRequestOptions,\n): Promise<Response> => {\n const { subEndpoint, method, referrer } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Session');\n if (subEndpointError) return subEndpointError;\n\n const SessionGetHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const handleSessionVerify = async (): Promise<Response> => {\n try {\n const sessionCookie = context.sessionTokenInCookie;\n if (!sessionCookie) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n const { data: decodedSession, errors } = ternDecodeJwtUnguarded(sessionCookie);\n if (errors) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n return SessionResponseHelper.createVerificationResponse(decodedSession);\n } catch (error) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n };\n\n switch (subEndpoint) {\n case 'verify':\n return handleSessionVerify();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n const SessionPostHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await extractSessionRequestData(context.request);\n if (error) return error;\n\n const csrfError = await validateCsrfToken(csrfToken);\n if (csrfError) return csrfError;\n\n const handleCreateSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n await refreshCookieWithIdToken(idToken, cookieStore, config, referrer, context.appCheckToken);\n return SessionResponseHelper.createSessionCreationResponse({\n success: true,\n message: 'Session created successfully',\n });\n } catch (error) {\n console.error('[SessionHandler - createsession] Error:', error);\n const errorMessage = error instanceof Error ? error.message : 'Session creation failed';\n return createApiErrorResponse('SESSION_CREATION_FAILED', errorMessage, 500);\n }\n };\n\n const handleRefreshSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n const decodedSession = ternDecodeJwtUnguarded(idToken);\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await refreshCookieWithIdToken(\n idToken,\n cookieStore,\n config,\n undefined,\n context.appCheckToken,\n );\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Session refresh failed';\n return createApiErrorResponse('REFRESH_FAILED', errorMessage, 500);\n }\n };\n\n const handleRevokeSession = async (cookieStore: NextCookieStore): Promise<Response> => {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n };\n\n switch (subEndpoint) {\n case 'createsession': {\n const idTokenError = validateIdToken(idToken);\n if (idTokenError) return idTokenError;\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleCreateSession(cookieStore, idToken!);\n }\n\n case 'refresh':\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleRefreshSession(cookieStore, idToken!);\n\n case 'revoke':\n return handleRevokeSession(cookieStore);\n\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return SessionGetHandler(subEndpoint as SessionSubEndpoint);\n\n case 'POST':\n return SessionPostHandler(subEndpoint as SessionSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\n\nconst signInEndpointHandler = async (\n context: RequestProcessorContext,\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Sign_ins');\n if (subEndpointError) return subEndpointError;\n\n const PostHandler = async (subEndpoint: SignInSubEndpoint): Promise<Response> => {\n const create = async (): Promise<Response> => {\n return await processSignInCreate(context);\n };\n\n const passwordResetEmail = async (): Promise<Response> => {\n try {\n const body = await context.request.json();\n const { email } = body;\n\n const emailError = validateEmail(email);\n if (emailError) return emailError;\n\n const backendClient = await ternSecureBackendClient();\n\n const response = await backendClient.signIn.resetPasswordEmail(FIREBASE_API_KEY, {\n email,\n requestType: 'PASSWORD_RESET',\n });\n\n if (!response) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_FAILED',\n 'Failed to send password reset email',\n 500,\n );\n }\n\n return createApiSuccessResponse({\n email,\n });\n } catch (error) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_ERROR',\n error instanceof Error\n ? error.message\n : 'An error occurred while sending password reset email',\n 500,\n );\n }\n };\n\n switch (subEndpoint) {\n case 'create':\n return create();\n case 'resetPasswordEmail':\n return passwordResetEmail();\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'POST':\n return PostHandler(subEndpoint as SignInSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n\n}\n\nexport { sessionEndpointHandler, signInEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/handlers.ts"],"sourcesContent":["import type { AuthenticateRequestOptions, RequestProcessorContext } from '@tern-secure/backend';\nimport { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { FIREBASE_API_KEY } from './constants';\nimport { refreshCookieWithIdToken } from './request';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n HttpResponseHelper,\n SessionResponseHelper,\n} from './responses';\nimport { processSignInCreate } from './signInCreateHandler';\nimport type { SessionSubEndpoint, SignInSubEndpoint, } from './types';\nimport {\n extractSessionRequestData,\n validateCsrfToken,\n validateEmail,\n validateIdToken,\n validateSubEndpointPresent,\n} from './validators';\n\nconst sessionEndpointHandler = async (\n context: RequestProcessorContext,\n config: AuthenticateRequestOptions,\n): Promise<Response> => {\n const { subEndpoint, method, referrer } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Session');\n if (subEndpointError) return subEndpointError;\n\n const SessionGetHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const handleSessionVerify = async (): Promise<Response> => {\n try {\n const sessionCookie = context.sessionTokenInCookie;\n if (!sessionCookie) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n const { data: decodedSession, errors } = ternDecodeJwtUnguarded(sessionCookie);\n if (errors) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n return SessionResponseHelper.createVerificationResponse(decodedSession);\n } catch (error) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n };\n\n switch (subEndpoint) {\n case 'verify':\n return handleSessionVerify();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n const SessionPostHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await extractSessionRequestData(context.request);\n if (error) return error;\n\n const csrfError = await validateCsrfToken(csrfToken);\n if (csrfError) return csrfError;\n\n const handleCreateSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n await refreshCookieWithIdToken(idToken, cookieStore, config, referrer, context.appCheckToken);\n return SessionResponseHelper.createSessionCreationResponse({\n success: true,\n message: 'Session created successfully',\n });\n } catch (error) {\n console.error('[SessionHandler - createsession] Error:', error);\n const errorMessage = error instanceof Error ? error.message : 'Session creation failed';\n return createApiErrorResponse('SESSION_CREATION_FAILED', errorMessage, 500);\n }\n };\n\n const handleRefreshSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n const decodedSession = ternDecodeJwtUnguarded(idToken);\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await refreshCookieWithIdToken(\n idToken,\n cookieStore,\n config,\n undefined,\n context.appCheckToken,\n );\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Session refresh failed';\n return createApiErrorResponse('REFRESH_FAILED', errorMessage, 500);\n }\n };\n\n const handleRevokeSession = async (cookieStore: NextCookieStore): Promise<Response> => {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n };\n\n switch (subEndpoint) {\n case 'createsession': {\n const idTokenError = validateIdToken(idToken);\n if (idTokenError) return idTokenError;\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleCreateSession(cookieStore, idToken!);\n }\n\n case 'refresh':\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleRefreshSession(cookieStore, idToken!);\n\n case 'revoke':\n return handleRevokeSession(cookieStore);\n\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return SessionGetHandler(subEndpoint as SessionSubEndpoint);\n\n case 'POST':\n return SessionPostHandler(subEndpoint as SessionSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\n\nconst signInEndpointHandler = async (\n context: RequestProcessorContext,\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Sign_ins');\n if (subEndpointError) return subEndpointError;\n\n const PostHandler = async (subEndpoint: SignInSubEndpoint): Promise<Response> => {\n const create = async (): Promise<Response> => {\n return await processSignInCreate(context);\n };\n\n const passwordResetEmail = async (): Promise<Response> => {\n try {\n const body = await context.request.json();\n const { email } = body;\n\n const emailError = validateEmail(email);\n if (emailError) return emailError;\n\n const backendClient = await ternSecureBackendClient();\n\n const response = await backendClient.signIn.resetPasswordEmail(FIREBASE_API_KEY, {\n email,\n requestType: 'PASSWORD_RESET',\n }, {\n appCheckToken: context.appCheckToken,\n });\n\n if (!response) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_FAILED',\n 'Failed to send password reset email',\n 500,\n );\n }\n\n return createApiSuccessResponse({\n email,\n });\n } catch (error) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_ERROR',\n error instanceof Error\n ? error.message\n : 'An error occurred while sending password reset email',\n 500,\n );\n }\n };\n\n switch (subEndpoint) {\n case 'create':\n return create();\n case 'resetPasswordEmail':\n return passwordResetEmail();\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'POST':\n return PostHandler(subEndpoint as SignInSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n\n}\n\nexport { sessionEndpointHandler, signInEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
@@ -128,6 +128,8 @@ const signInEndpointHandler = async (context) => {
128
128
  const response = await backendClient.signIn.resetPasswordEmail(FIREBASE_API_KEY, {
129
129
  email,
130
130
  requestType: "PASSWORD_RESET"
131
+ }, {
132
+ appCheckToken: context.appCheckToken
131
133
  });
132
134
  if (!response) {
133
135
  return createApiErrorResponse(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/handlers.ts"],"sourcesContent":["import type { AuthenticateRequestOptions, RequestProcessorContext } from '@tern-secure/backend';\nimport { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { FIREBASE_API_KEY } from './constants';\nimport { refreshCookieWithIdToken } from './request';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n HttpResponseHelper,\n SessionResponseHelper,\n} from './responses';\nimport { processSignInCreate } from './signInCreateHandler';\nimport type { SessionSubEndpoint, SignInSubEndpoint, } from './types';\nimport {\n extractSessionRequestData,\n validateCsrfToken,\n validateEmail,\n validateIdToken,\n validateSubEndpointPresent,\n} from './validators';\n\nconst sessionEndpointHandler = async (\n context: RequestProcessorContext,\n config: AuthenticateRequestOptions,\n): Promise<Response> => {\n const { subEndpoint, method, referrer } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Session');\n if (subEndpointError) return subEndpointError;\n\n const SessionGetHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const handleSessionVerify = async (): Promise<Response> => {\n try {\n const sessionCookie = context.sessionTokenInCookie;\n if (!sessionCookie) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n const { data: decodedSession, errors } = ternDecodeJwtUnguarded(sessionCookie);\n if (errors) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n return SessionResponseHelper.createVerificationResponse(decodedSession);\n } catch (error) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n };\n\n switch (subEndpoint) {\n case 'verify':\n return handleSessionVerify();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n const SessionPostHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await extractSessionRequestData(context.request);\n if (error) return error;\n\n const csrfError = await validateCsrfToken(csrfToken);\n if (csrfError) return csrfError;\n\n const handleCreateSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n await refreshCookieWithIdToken(idToken, cookieStore, config, referrer, context.appCheckToken);\n return SessionResponseHelper.createSessionCreationResponse({\n success: true,\n message: 'Session created successfully',\n });\n } catch (error) {\n console.error('[SessionHandler - createsession] Error:', error);\n const errorMessage = error instanceof Error ? error.message : 'Session creation failed';\n return createApiErrorResponse('SESSION_CREATION_FAILED', errorMessage, 500);\n }\n };\n\n const handleRefreshSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n const decodedSession = ternDecodeJwtUnguarded(idToken);\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await refreshCookieWithIdToken(\n idToken,\n cookieStore,\n config,\n undefined,\n context.appCheckToken,\n );\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Session refresh failed';\n return createApiErrorResponse('REFRESH_FAILED', errorMessage, 500);\n }\n };\n\n const handleRevokeSession = async (cookieStore: NextCookieStore): Promise<Response> => {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n };\n\n switch (subEndpoint) {\n case 'createsession': {\n const idTokenError = validateIdToken(idToken);\n if (idTokenError) return idTokenError;\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleCreateSession(cookieStore, idToken!);\n }\n\n case 'refresh':\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleRefreshSession(cookieStore, idToken!);\n\n case 'revoke':\n return handleRevokeSession(cookieStore);\n\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return SessionGetHandler(subEndpoint as SessionSubEndpoint);\n\n case 'POST':\n return SessionPostHandler(subEndpoint as SessionSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\n\nconst signInEndpointHandler = async (\n context: RequestProcessorContext,\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Sign_ins');\n if (subEndpointError) return subEndpointError;\n\n const PostHandler = async (subEndpoint: SignInSubEndpoint): Promise<Response> => {\n const create = async (): Promise<Response> => {\n return await processSignInCreate(context);\n };\n\n const passwordResetEmail = async (): Promise<Response> => {\n try {\n const body = await context.request.json();\n const { email } = body;\n\n const emailError = validateEmail(email);\n if (emailError) return emailError;\n\n const backendClient = await ternSecureBackendClient();\n\n const response = await backendClient.signIn.resetPasswordEmail(FIREBASE_API_KEY, {\n email,\n requestType: 'PASSWORD_RESET',\n });\n\n if (!response) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_FAILED',\n 'Failed to send password reset email',\n 500,\n );\n }\n\n return createApiSuccessResponse({\n email,\n });\n } catch (error) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_ERROR',\n error instanceof Error\n ? error.message\n : 'An error occurred while sending password reset email',\n 500,\n );\n }\n };\n\n switch (subEndpoint) {\n case 'create':\n return create();\n case 'resetPasswordEmail':\n return passwordResetEmail();\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'POST':\n return PostHandler(subEndpoint as SignInSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n\n}\n\nexport { sessionEndpointHandler, signInEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/handlers.ts"],"sourcesContent":["import type { AuthenticateRequestOptions, RequestProcessorContext } from '@tern-secure/backend';\nimport { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { FIREBASE_API_KEY } from './constants';\nimport { refreshCookieWithIdToken } from './request';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n HttpResponseHelper,\n SessionResponseHelper,\n} from './responses';\nimport { processSignInCreate } from './signInCreateHandler';\nimport type { SessionSubEndpoint, SignInSubEndpoint, } from './types';\nimport {\n extractSessionRequestData,\n validateCsrfToken,\n validateEmail,\n validateIdToken,\n validateSubEndpointPresent,\n} from './validators';\n\nconst sessionEndpointHandler = async (\n context: RequestProcessorContext,\n config: AuthenticateRequestOptions,\n): Promise<Response> => {\n const { subEndpoint, method, referrer } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Session');\n if (subEndpointError) return subEndpointError;\n\n const SessionGetHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const handleSessionVerify = async (): Promise<Response> => {\n try {\n const sessionCookie = context.sessionTokenInCookie;\n if (!sessionCookie) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n const { data: decodedSession, errors } = ternDecodeJwtUnguarded(sessionCookie);\n if (errors) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n return SessionResponseHelper.createVerificationResponse(decodedSession);\n } catch (error) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n };\n\n switch (subEndpoint) {\n case 'verify':\n return handleSessionVerify();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n const SessionPostHandler = async (subEndpoint: SessionSubEndpoint): Promise<Response> => {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await extractSessionRequestData(context.request);\n if (error) return error;\n\n const csrfError = await validateCsrfToken(csrfToken);\n if (csrfError) return csrfError;\n\n const handleCreateSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n await refreshCookieWithIdToken(idToken, cookieStore, config, referrer, context.appCheckToken);\n return SessionResponseHelper.createSessionCreationResponse({\n success: true,\n message: 'Session created successfully',\n });\n } catch (error) {\n console.error('[SessionHandler - createsession] Error:', error);\n const errorMessage = error instanceof Error ? error.message : 'Session creation failed';\n return createApiErrorResponse('SESSION_CREATION_FAILED', errorMessage, 500);\n }\n };\n\n const handleRefreshSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n const decodedSession = ternDecodeJwtUnguarded(idToken);\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await refreshCookieWithIdToken(\n idToken,\n cookieStore,\n config,\n undefined,\n context.appCheckToken,\n );\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Session refresh failed';\n return createApiErrorResponse('REFRESH_FAILED', errorMessage, 500);\n }\n };\n\n const handleRevokeSession = async (cookieStore: NextCookieStore): Promise<Response> => {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n };\n\n switch (subEndpoint) {\n case 'createsession': {\n const idTokenError = validateIdToken(idToken);\n if (idTokenError) return idTokenError;\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleCreateSession(cookieStore, idToken!);\n }\n\n case 'refresh':\n //eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return handleRefreshSession(cookieStore, idToken!);\n\n case 'revoke':\n return handleRevokeSession(cookieStore);\n\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return SessionGetHandler(subEndpoint as SessionSubEndpoint);\n\n case 'POST':\n return SessionPostHandler(subEndpoint as SessionSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\n\nconst signInEndpointHandler = async (\n context: RequestProcessorContext,\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n // Validate sub-endpoint exists\n const subEndpointError = validateSubEndpointPresent(context, 'Sign_ins');\n if (subEndpointError) return subEndpointError;\n\n const PostHandler = async (subEndpoint: SignInSubEndpoint): Promise<Response> => {\n const create = async (): Promise<Response> => {\n return await processSignInCreate(context);\n };\n\n const passwordResetEmail = async (): Promise<Response> => {\n try {\n const body = await context.request.json();\n const { email } = body;\n\n const emailError = validateEmail(email);\n if (emailError) return emailError;\n\n const backendClient = await ternSecureBackendClient();\n\n const response = await backendClient.signIn.resetPasswordEmail(FIREBASE_API_KEY, {\n email,\n requestType: 'PASSWORD_RESET',\n }, {\n appCheckToken: context.appCheckToken,\n });\n\n if (!response) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_FAILED',\n 'Failed to send password reset email',\n 500,\n );\n }\n\n return createApiSuccessResponse({\n email,\n });\n } catch (error) {\n return createApiErrorResponse(\n 'PASSWORD_RESET_ERROR',\n error instanceof Error\n ? error.message\n : 'An error occurred while sending password reset email',\n 500,\n );\n }\n };\n\n switch (subEndpoint) {\n case 'create':\n return create();\n case 'resetPasswordEmail':\n return passwordResetEmail();\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n };\n\n switch (method) {\n case 'POST':\n return PostHandler(subEndpoint as SignInSubEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n\n}\n\nexport { sessionEndpointHandler, signInEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAwBhG,QAAA,MAAM,sBAAsB,GAC1B,SAAS,uBAAuB,EAChC,QAAQ,0BAA0B,KACjC,OAAO,CAAC,QAAQ,CAuHlB,CAAA;AAGD,QAAA,MAAM,qBAAqB,GACzB,SAAS,uBAAuB,KAC/B,OAAO,CAAC,QAAQ,CAmElB,CAAA;AAED,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAwBhG,QAAA,MAAM,sBAAsB,GAC1B,SAAS,uBAAuB,EAChC,QAAQ,0BAA0B,KACjC,OAAO,CAAC,QAAQ,CAuHlB,CAAA;AAGD,QAAA,MAAM,qBAAqB,GACzB,SAAS,uBAAuB,KAC/B,OAAO,CAAC,QAAQ,CAqElB,CAAA;AAED,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tern-secure/nextjs",
3
- "version": "5.2.0-canary.v20251202172616",
3
+ "version": "5.2.0-canary.v20251202183844",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -61,10 +61,10 @@
61
61
  "jose": "^5.9.6",
62
62
  "server-only": "^0.0.1",
63
63
  "tslib": "2.8.1",
64
- "@tern-secure/backend": "1.2.0-canary.v20251202172616",
65
- "@tern-secure/react": "1.2.0-canary.v20251202172616",
66
- "@tern-secure/shared": "1.3.0-canary.v20251202172616",
67
- "@tern-secure/types": "1.1.0-canary.v20251202172616"
64
+ "@tern-secure/backend": "1.2.0-canary.v20251202183844",
65
+ "@tern-secure/react": "1.2.0-canary.v20251202183844",
66
+ "@tern-secure/shared": "1.3.0-canary.v20251202183844",
67
+ "@tern-secure/types": "1.1.0-canary.v20251202183844"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "firebase": "^12.0.0",