@tern-secure/nextjs 5.1.8 → 5.1.10
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/cjs/__tests__/gemini_fnTernSecureNextHandler.bench.js +31 -0
- package/dist/cjs/__tests__/gemini_fnTernSecureNextHandler.bench.js.map +1 -0
- package/dist/cjs/app-router/admin/actions.js +62 -0
- package/dist/cjs/app-router/admin/actions.js.map +1 -0
- package/dist/cjs/app-router/admin/constants.js +29 -0
- package/dist/cjs/app-router/admin/constants.js.map +1 -0
- package/dist/cjs/app-router/admin/fnValidators.js +295 -0
- package/dist/cjs/app-router/admin/fnValidators.js.map +1 -0
- package/dist/cjs/app-router/admin/index.js +16 -3
- package/dist/cjs/app-router/admin/index.js.map +1 -1
- package/dist/cjs/app-router/admin/responses.js +120 -0
- package/dist/cjs/app-router/admin/responses.js.map +1 -0
- package/dist/cjs/app-router/admin/sessionHandlers.js +167 -0
- package/dist/cjs/app-router/admin/sessionHandlers.js.map +1 -0
- package/dist/cjs/app-router/admin/ternsecureNextjsHandler.js +84 -0
- package/dist/cjs/app-router/admin/ternsecureNextjsHandler.js.map +1 -0
- package/dist/cjs/app-router/admin/types.js +127 -0
- package/dist/cjs/app-router/admin/types.js.map +1 -0
- package/dist/cjs/app-router/admin/utils.js +107 -0
- package/dist/cjs/app-router/admin/utils.js.map +1 -0
- package/dist/cjs/app-router/admin/validators.js +217 -0
- package/dist/cjs/app-router/admin/validators.js.map +1 -0
- package/dist/cjs/app-router/client/TernSecureProvider.js +2 -6
- package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -1
- package/dist/cjs/app-router/server/auth.js +100 -0
- package/dist/cjs/app-router/server/auth.js.map +1 -0
- package/dist/cjs/app-router/server/utils.js +87 -0
- package/dist/cjs/app-router/server/utils.js.map +1 -0
- package/dist/cjs/boundary/components.js +4 -7
- package/dist/cjs/boundary/components.js.map +1 -1
- package/dist/cjs/{components/uiComponents.js → constants.js} +17 -18
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/index.js +4 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/constant.js +38 -0
- package/dist/cjs/server/constant.js.map +1 -0
- package/dist/cjs/server/edge-session.js +118 -24
- package/dist/cjs/server/edge-session.js.map +1 -1
- package/dist/cjs/server/headers-utils.js +70 -0
- package/dist/cjs/server/headers-utils.js.map +1 -0
- package/dist/cjs/server/index.js +8 -6
- package/dist/cjs/server/index.js.map +1 -1
- package/dist/cjs/server/jwt-edge.js +47 -19
- package/dist/cjs/server/jwt-edge.js.map +1 -1
- package/dist/cjs/server/jwt.js +11 -4
- package/dist/cjs/server/jwt.js.map +1 -1
- package/dist/cjs/server/nextErrors.js +131 -0
- package/dist/cjs/server/nextErrors.js.map +1 -0
- package/dist/cjs/server/nextFetcher.js +31 -0
- package/dist/cjs/server/nextFetcher.js.map +1 -0
- package/dist/cjs/server/node/SessionTernSecure.js +55 -0
- package/dist/cjs/server/node/SessionTernSecure.js.map +1 -0
- package/dist/cjs/server/{auth.js → node/auth.js} +11 -20
- package/dist/cjs/server/node/auth.js.map +1 -0
- package/dist/cjs/server/node/index.js +40 -0
- package/dist/cjs/server/node/index.js.map +1 -0
- package/dist/cjs/server/node/node-session.js +60 -0
- package/dist/cjs/server/node/node-session.js.map +1 -0
- package/dist/cjs/server/node/ternSecureNodeMiddleware.js +182 -0
- package/dist/cjs/server/node/ternSecureNodeMiddleware.js.map +1 -0
- package/dist/cjs/server/protect.js +90 -0
- package/dist/cjs/server/protect.js.map +1 -0
- package/dist/cjs/server/redirect.js +84 -0
- package/dist/cjs/server/redirect.js.map +1 -0
- package/dist/cjs/server/routeMatcher.js +36 -0
- package/dist/cjs/server/routeMatcher.js.map +1 -0
- package/dist/cjs/server/sdk-versions.js +43 -0
- package/dist/cjs/server/sdk-versions.js.map +1 -0
- package/dist/cjs/server/session-store.js.map +1 -1
- package/dist/cjs/server/ternSecureEdgeMiddleware.js +298 -0
- package/dist/cjs/server/ternSecureEdgeMiddleware.js.map +1 -0
- package/dist/cjs/server/ternSecureFireMiddleware.js +192 -0
- package/dist/cjs/server/ternSecureFireMiddleware.js.map +1 -0
- package/dist/cjs/server/types.js.map +1 -1
- package/dist/cjs/server/utils.js +115 -2
- package/dist/cjs/server/utils.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/NextCookieAdapter.js +44 -0
- package/dist/cjs/utils/NextCookieAdapter.js.map +1 -0
- package/dist/cjs/utils/allNextProviderProps.js +10 -24
- package/dist/cjs/utils/allNextProviderProps.js.map +1 -1
- package/dist/cjs/utils/config.js +38 -2
- package/dist/cjs/utils/config.js.map +1 -1
- package/dist/cjs/utils/construct.js.map +1 -1
- package/dist/cjs/utils/fireconfig.js +38 -0
- package/dist/cjs/utils/fireconfig.js.map +1 -0
- package/dist/cjs/utils/logger.js +101 -0
- package/dist/cjs/utils/logger.js.map +1 -0
- package/dist/cjs/utils/redis.js +33 -0
- package/dist/cjs/utils/redis.js.map +1 -0
- package/dist/cjs/utils/response.js +38 -0
- package/dist/cjs/utils/response.js.map +1 -0
- package/dist/cjs/utils/serverRedirectAuth.js +39 -0
- package/dist/cjs/utils/serverRedirectAuth.js.map +1 -0
- package/dist/cjs/utils/ternsecure-sw.js +1 -1
- package/dist/cjs/utils/ternsecure-sw.js.map +1 -1
- package/dist/cjs/utils/withLogger.js +82 -0
- package/dist/cjs/utils/withLogger.js.map +1 -0
- package/dist/esm/__tests__/gemini_fnTernSecureNextHandler.bench.js +30 -0
- package/dist/esm/__tests__/gemini_fnTernSecureNextHandler.bench.js.map +1 -0
- package/dist/esm/app-router/admin/actions.js +40 -0
- package/dist/esm/app-router/admin/actions.js.map +1 -0
- package/dist/esm/app-router/admin/constants.js +5 -0
- package/dist/esm/app-router/admin/constants.js.map +1 -0
- package/dist/esm/app-router/admin/fnValidators.js +270 -0
- package/dist/esm/app-router/admin/fnValidators.js.map +1 -0
- package/dist/esm/app-router/admin/index.js +16 -2
- package/dist/esm/app-router/admin/index.js.map +1 -1
- package/dist/esm/app-router/admin/responses.js +93 -0
- package/dist/esm/app-router/admin/responses.js.map +1 -0
- package/dist/esm/app-router/admin/sessionHandlers.js +131 -0
- package/dist/esm/app-router/admin/sessionHandlers.js.map +1 -0
- package/dist/esm/app-router/admin/ternsecureNextjsHandler.js +62 -0
- package/dist/esm/app-router/admin/ternsecureNextjsHandler.js.map +1 -0
- package/dist/esm/app-router/admin/types.js +98 -0
- package/dist/esm/app-router/admin/types.js.map +1 -0
- package/dist/esm/app-router/admin/utils.js +80 -0
- package/dist/esm/app-router/admin/utils.js.map +1 -0
- package/dist/esm/app-router/admin/validators.js +189 -0
- package/dist/esm/app-router/admin/validators.js.map +1 -0
- package/dist/esm/app-router/client/TernSecureProvider.js +2 -6
- package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -1
- package/dist/esm/app-router/server/auth.js +81 -0
- package/dist/esm/app-router/server/auth.js.map +1 -0
- package/dist/esm/app-router/server/utils.js +51 -0
- package/dist/esm/app-router/server/utils.js.map +1 -0
- package/dist/esm/boundary/components.js +4 -7
- package/dist/esm/boundary/components.js.map +1 -1
- package/dist/esm/constants.js +17 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +5 -11
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/constant.js +11 -0
- package/dist/esm/server/constant.js.map +1 -0
- package/dist/esm/server/edge-session.js +113 -22
- package/dist/esm/server/edge-session.js.map +1 -1
- package/dist/esm/server/headers-utils.js +41 -0
- package/dist/esm/server/headers-utils.js.map +1 -0
- package/dist/esm/server/index.js +9 -3
- package/dist/esm/server/index.js.map +1 -1
- package/dist/esm/server/jwt-edge.js +48 -20
- package/dist/esm/server/jwt-edge.js.map +1 -1
- package/dist/esm/server/jwt.js +12 -5
- package/dist/esm/server/jwt.js.map +1 -1
- package/dist/esm/server/nextErrors.js +97 -0
- package/dist/esm/server/nextErrors.js.map +1 -0
- package/dist/esm/server/nextFetcher.js +7 -0
- package/dist/esm/server/nextFetcher.js.map +1 -0
- package/dist/esm/server/node/SessionTernSecure.js +31 -0
- package/dist/esm/server/node/SessionTernSecure.js.map +1 -0
- package/dist/esm/server/{auth.js → node/auth.js} +11 -20
- package/dist/esm/server/node/auth.js.map +1 -0
- package/dist/esm/server/node/index.js +19 -0
- package/dist/esm/server/node/index.js.map +1 -0
- package/dist/esm/server/node/node-session.js +36 -0
- package/dist/esm/server/node/node-session.js.map +1 -0
- package/dist/esm/server/node/ternSecureNodeMiddleware.js +165 -0
- package/dist/esm/server/node/ternSecureNodeMiddleware.js.map +1 -0
- package/dist/esm/server/protect.js +66 -0
- package/dist/esm/server/protect.js.map +1 -0
- package/dist/esm/server/redirect.js +60 -0
- package/dist/esm/server/redirect.js.map +1 -0
- package/dist/esm/server/routeMatcher.js +12 -0
- package/dist/esm/server/routeMatcher.js.map +1 -0
- package/dist/esm/server/sdk-versions.js +8 -0
- package/dist/esm/server/sdk-versions.js.map +1 -0
- package/dist/esm/server/session-store.js.map +1 -1
- package/dist/esm/server/ternSecureEdgeMiddleware.js +286 -0
- package/dist/esm/server/ternSecureEdgeMiddleware.js.map +1 -0
- package/dist/esm/server/ternSecureFireMiddleware.js +179 -0
- package/dist/esm/server/ternSecureFireMiddleware.js.map +1 -0
- package/dist/esm/server/utils.js +99 -1
- package/dist/esm/server/utils.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/NextCookieAdapter.js +20 -0
- package/dist/esm/utils/NextCookieAdapter.js.map +1 -0
- package/dist/esm/utils/allNextProviderProps.js +10 -24
- package/dist/esm/utils/allNextProviderProps.js.map +1 -1
- package/dist/esm/utils/config.js +34 -1
- package/dist/esm/utils/config.js.map +1 -1
- package/dist/esm/utils/construct.js +1 -1
- package/dist/esm/utils/construct.js.map +1 -1
- package/dist/esm/utils/fireconfig.js +14 -0
- package/dist/esm/utils/fireconfig.js.map +1 -0
- package/dist/esm/utils/logger.js +74 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/dist/esm/utils/redis.js +9 -0
- package/dist/esm/utils/redis.js.map +1 -0
- package/dist/esm/utils/response.js +13 -0
- package/dist/esm/utils/response.js.map +1 -0
- package/dist/esm/utils/serverRedirectAuth.js +17 -0
- package/dist/esm/utils/serverRedirectAuth.js.map +1 -0
- package/dist/esm/utils/ternsecure-sw.js +1 -1
- package/dist/esm/utils/ternsecure-sw.js.map +1 -1
- package/dist/esm/utils/withLogger.js +57 -0
- package/dist/esm/utils/withLogger.js.map +1 -0
- package/package.json +21 -7
- package/server/node/package.json +5 -0
- package/server/package.json +5 -0
- package/dist/cjs/app-router/admin/sessionHandler.js +0 -74
- package/dist/cjs/app-router/admin/sessionHandler.js.map +0 -1
- package/dist/cjs/app-router/client/actions.js +0 -4
- package/dist/cjs/app-router/client/actions.js.map +0 -1
- package/dist/cjs/components/uiComponents.js.map +0 -1
- package/dist/cjs/server/auth.js.map +0 -1
- package/dist/cjs/server/ternSecureMiddleware.js +0 -95
- package/dist/cjs/server/ternSecureMiddleware.js.map +0 -1
- package/dist/cjs/utils/tern-ui-script.js +0 -78
- package/dist/cjs/utils/tern-ui-script.js.map +0 -1
- package/dist/esm/app-router/admin/sessionHandler.js +0 -50
- package/dist/esm/app-router/admin/sessionHandler.js.map +0 -1
- package/dist/esm/app-router/client/actions.js +0 -3
- package/dist/esm/app-router/client/actions.js.map +0 -1
- package/dist/esm/components/uiComponents.js +0 -21
- package/dist/esm/components/uiComponents.js.map +0 -1
- package/dist/esm/server/auth.js.map +0 -1
- package/dist/esm/server/ternSecureMiddleware.js +0 -69
- package/dist/esm/server/ternSecureMiddleware.js.map +0 -1
- package/dist/esm/utils/tern-ui-script.js +0 -44
- package/dist/esm/utils/tern-ui-script.js.map +0 -1
- package/dist/types/app-router/admin/index.d.ts +0 -2
- package/dist/types/app-router/admin/index.d.ts.map +0 -1
- package/dist/types/app-router/admin/sessionHandler.d.ts +0 -3
- package/dist/types/app-router/admin/sessionHandler.d.ts.map +0 -1
- package/dist/types/app-router/client/TernSecureProvider.d.ts +0 -25
- package/dist/types/app-router/client/TernSecureProvider.d.ts.map +0 -1
- package/dist/types/app-router/client/actions.d.ts +0 -2
- package/dist/types/app-router/client/actions.d.ts.map +0 -1
- package/dist/types/app-router/route-handler/internal-route.d.ts +0 -2
- package/dist/types/app-router/route-handler/internal-route.d.ts.map +0 -1
- package/dist/types/boundary/components.d.ts +0 -2
- package/dist/types/boundary/components.d.ts.map +0 -1
- package/dist/types/boundary/hooks.d.ts +0 -2
- package/dist/types/boundary/hooks.d.ts.map +0 -1
- package/dist/types/components/uiComponents.d.ts +0 -6
- package/dist/types/components/uiComponents.d.ts.map +0 -1
- package/dist/types/errors.d.ts +0 -44
- package/dist/types/errors.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -5
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/server/auth.d.ts +0 -23
- package/dist/types/server/auth.d.ts.map +0 -1
- package/dist/types/server/crypto.d.ts +0 -3
- package/dist/types/server/crypto.d.ts.map +0 -1
- package/dist/types/server/ctx-store.d.ts +0 -24
- package/dist/types/server/ctx-store.d.ts.map +0 -1
- package/dist/types/server/edge-session.d.ts +0 -4
- package/dist/types/server/edge-session.d.ts.map +0 -1
- package/dist/types/server/index.d.ts +0 -4
- package/dist/types/server/index.d.ts.map +0 -1
- package/dist/types/server/jwt-edge.d.ts +0 -20
- package/dist/types/server/jwt-edge.d.ts.map +0 -1
- package/dist/types/server/jwt.d.ts +0 -20
- package/dist/types/server/jwt.d.ts.map +0 -1
- package/dist/types/server/session-store.d.ts +0 -30
- package/dist/types/server/session-store.d.ts.map +0 -1
- package/dist/types/server/ternSecureMiddleware.d.ts +0 -20
- package/dist/types/server/ternSecureMiddleware.d.ts.map +0 -1
- package/dist/types/server/types.d.ts +0 -26
- package/dist/types/server/types.d.ts.map +0 -1
- package/dist/types/server/utils.d.ts +0 -22
- package/dist/types/server/utils.d.ts.map +0 -1
- package/dist/types/types.d.ts +0 -112
- package/dist/types/types.d.ts.map +0 -1
- package/dist/types/utils/admin-init.d.ts +0 -2
- package/dist/types/utils/admin-init.d.ts.map +0 -1
- package/dist/types/utils/allNextProviderProps.d.ts +0 -6
- package/dist/types/utils/allNextProviderProps.d.ts.map +0 -1
- package/dist/types/utils/client-init.d.ts +0 -2
- package/dist/types/utils/client-init.d.ts.map +0 -1
- package/dist/types/utils/config.d.ts +0 -35
- package/dist/types/utils/config.d.ts.map +0 -1
- package/dist/types/utils/construct.d.ts +0 -38
- package/dist/types/utils/construct.d.ts.map +0 -1
- package/dist/types/utils/create-styles.d.ts +0 -99
- package/dist/types/utils/create-styles.d.ts.map +0 -1
- package/dist/types/utils/redirect.d.ts +0 -9
- package/dist/types/utils/redirect.d.ts.map +0 -1
- package/dist/types/utils/tern-ui-script.d.ts +0 -9
- package/dist/types/utils/tern-ui-script.d.ts.map +0 -1
- package/dist/types/utils/ternsecure-sw.d.ts +0 -8
- package/dist/types/utils/ternsecure-sw.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/server/ternSecureFireMiddleware.ts"],"sourcesContent":["import type {\n AuthObject,\n RequestOptions,\n TernSecureRequest,\n} from '@tern-secure/backend';\nimport {\n constants,\n createFireClient,\n createTernSecureRequest,\n} from '@tern-secure/backend';\nimport type {\n TernSecureConfig,\n} from '@tern-secure/types';\nimport { notFound as nextjsNotFound } from 'next/navigation';\nimport type { NextMiddleware,NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\n\nimport { isRedirect, setHeader } from '../utils/response';\nimport { serverRedirectWithAuth } from '../utils/serverRedirectAuth';\nimport { API_URL, API_VERSION,SIGN_IN_URL, SIGN_UP_URL } from './constant';\nimport {\n isNextjsNotFoundError,\n isNextjsRedirectError,\n isRedirectToSignInError,\n isRedirectToSignUpError,\n nextjsRedirectError,\n redirectToSignInError,\n redirectToSignUpError,\n} from './nextErrors';\nimport { type AuthProtect,createProtect } from './protect';\nimport { createRedirect, type RedirectFun } from './redirect';\nimport type {\n NextMiddlewareEvtParam,\n NextMiddlewareRequestParam,\n NextMiddlewareReturn,\n} from './types';\nimport { decorateRequest } from './utils';\n\nexport type MiddlewareAuthObject = AuthObject & {\n redirectToSignIn: RedirectFun<Response>;\n redirectToSignUp: RedirectFun<Response>;\n};\n\nexport interface MiddlewareAuth {\n (): Promise<MiddlewareAuthObject>;\n\n protect: AuthProtect;\n}\n\ntype MiddlewareHandler = (\n auth: MiddlewareAuth,\n request: NextMiddlewareRequestParam,\n event: NextMiddlewareEvtParam,\n) => NextMiddlewareReturn;\n\nexport interface MiddlewareOptions extends RequestOptions {\n debug?: boolean;\n firebaseOptions?: TernSecureConfig;\n}\ntype MiddlewareOptionsCallback = (\n req: NextRequest,\n) => MiddlewareOptions | Promise<MiddlewareOptions>;\n\ninterface TernSecureMiddleware {\n /**\n * @example\n * export default ternSecureMiddleware((auth, request, event) => { ... }, options);\n */\n (handler: MiddlewareHandler, options?: MiddlewareOptions): NextMiddleware;\n\n /**\n * @example\n * export default ternSecureMiddleware((auth, request, event) => { ... }, (req) => options);\n */\n (handler: MiddlewareHandler, options?: MiddlewareOptionsCallback): NextMiddleware;\n\n /**\n * @example\n * export default ternSecureMiddleware(options);\n */\n (options?: MiddlewareOptions): NextMiddleware;\n /**\n * @example\n * export default ternSecureMiddleware;\n */\n (request: NextMiddlewareRequestParam, event: NextMiddlewareEvtParam): NextMiddlewareReturn;\n}\n\nconst backendClientDefaultOptions = {\n apiUrl: API_URL,\n apiVersion: API_VERSION,\n};\n\nconst ternSecureFireClient = async () => {\n return createFireClientWithOptions({});\n};\n\nconst createFireClientWithOptions: typeof createFireClient = options => {\n return createFireClient({\n ...backendClientDefaultOptions,\n ...options,\n });\n};\n\nexport const ternSecureMiddleware = ((\n ...args: unknown[]\n): NextMiddleware | NextMiddlewareReturn => {\n const [request, event] = parseRequestAndEvent(args);\n const [handler, params] = parseHandlerAndOptions(args);\n\n const middleware = () => {\n const runMiddleware: NextMiddleware = async (request, event) => {\n const resolvedParams = typeof params === 'function' ? await params(request) : params;\n const signInUrl = resolvedParams.signInUrl || SIGN_IN_URL;\n const signUpUrl = resolvedParams.signUpUrl || SIGN_UP_URL;\n\n const options = {\n signInUrl,\n signUpUrl,\n ...resolvedParams,\n };\n\n const reqBackendClient = await ternSecureFireClient();\n const ternSecureRequest = createTernSecureRequest(request);\n\n const requestStateClient = await reqBackendClient.authenticateRequest(\n ternSecureRequest,\n options,\n );\n\n const authObjectClient = requestStateClient.auth();\n\n const { redirectToSignIn } = createMiddlewareRedirects(ternSecureRequest);\n\n const { redirectToSignUp } = createMiddlewareRedirects(ternSecureRequest);\n\n const protect = await createMiddlewareProtect(\n ternSecureRequest,\n authObjectClient,\n redirectToSignIn,\n );\n\n const authObj: MiddlewareAuthObject = Object.assign(authObjectClient, {\n redirectToSignIn,\n redirectToSignUp,\n });\n\n const authHandler = () => Promise.resolve(authObj);\n authHandler.protect = protect;\n\n let handlerResult: Response = NextResponse.next();\n\n try {\n const userHandlerResult = await handler?.(authHandler, request, event);\n handlerResult = userHandlerResult || handlerResult;\n } catch (error: any) {\n handlerResult = handleControlError(error, ternSecureRequest, request);\n }\n\n if (requestStateClient.headers) {\n requestStateClient.headers.forEach((value, key) => {\n handlerResult.headers.append(key, value);\n });\n }\n\n if (isRedirect(handlerResult)) {\n return serverRedirectWithAuth(ternSecureRequest, handlerResult);\n }\n\n decorateRequest(ternSecureRequest, handlerResult, requestStateClient);\n return handlerResult;\n };\n\n const nextMiddleware: NextMiddleware = async (request, event) => {\n console.log('[TernSecureMiddleware] Request URL:', request.url);\n console.log('[TernSecureMiddleware] Request pathname:', request.nextUrl.pathname);\n return runMiddleware(request, event);\n };\n\n if (request && event) {\n return nextMiddleware(request, event);\n }\n\n return nextMiddleware;\n };\n return middleware();\n}) as TernSecureMiddleware;\n\nconst parseRequestAndEvent = (args: unknown[]) => {\n return [\n args[0] instanceof Request ? args[0] : undefined,\n args[0] instanceof Request ? args[1] : undefined,\n ] as [NextMiddlewareRequestParam | undefined, NextMiddlewareEvtParam | undefined];\n};\n\nconst parseHandlerAndOptions = (args: unknown[]) => {\n return [\n typeof args[0] === 'function' ? args[0] : undefined,\n (args.length === 2 ? args[1] : typeof args[0] === 'function' ? {} : args[0]) || {},\n ] as [MiddlewareHandler | undefined, MiddlewareOptions | MiddlewareOptionsCallback];\n};\n\nconst isFirebaseRequest = (request: NextMiddlewareRequestParam) => \n request.nextUrl.pathname.startsWith('/__/');\n\nconst finalTarget = (request: NextMiddlewareRequestParam) => {\n const finalTargetUrl = request.nextUrl.searchParams.get('finalTarget');\n return finalTargetUrl ? new URL(finalTargetUrl, request.url) : undefined;\n}\n\nconst isFirebaseCookieRequest = (request: NextMiddlewareRequestParam) => \n request.nextUrl.pathname === '/__cookies__';\n\n/**\n * Create middleware redirect functions\n */\nconst createMiddlewareRedirects = (ternSecureRequest: TernSecureRequest) => {\n const redirectToSignIn: MiddlewareAuthObject['redirectToSignIn'] = (opts = {}) => {\n const url = ternSecureRequest.ternUrl.toString();\n redirectToSignInError(url, opts.returnBackUrl);\n };\n\n const redirectToSignUp: MiddlewareAuthObject['redirectToSignUp'] = (opts = {}) => {\n const url = ternSecureRequest.ternUrl.toString();\n redirectToSignUpError(url, opts.returnBackUrl);\n };\n\n return { redirectToSignIn, redirectToSignUp };\n};\n\nconst createMiddlewareProtect = (\n ternSecureRequest: TernSecureRequest,\n authObject: AuthObject,\n redirectToSignIn: RedirectFun<Response>,\n) => {\n return (async (params: any, options: any) => {\n const notFound = () => nextjsNotFound();\n\n const redirect = (url: string) =>\n nextjsRedirectError(url, {\n redirectUrl: url,\n });\n\n return createProtect({\n request: ternSecureRequest,\n redirect,\n notFound,\n authObject,\n redirectToSignIn,\n })(params, options);\n }) as unknown as Promise<AuthProtect>;\n};\n\nexport const redirectAdapter = (url: string | URL) => {\n return NextResponse.redirect(url, {\n headers: { [constants.Headers.TernSecureRedirectTo]: 'true' },\n });\n};\n\n/**\n * Handle control flow errors in middleware\n */\nconst handleControlError = (\n error: any,\n ternSecureRequest: TernSecureRequest,\n nextrequest: NextRequest,\n): Response => {\n if (isNextjsNotFoundError(error)) {\n return setHeader(\n NextResponse.rewrite(new URL(`/tern_${Date.now()}`, nextrequest.url)),\n constants.Headers.AuthReason,\n 'protect-rewrite',\n );\n }\n\n const isRedirectToSignIn = isRedirectToSignInError(error);\n const isRedirectToSignUp = isRedirectToSignUpError(error);\n\n if (isRedirectToSignIn || isRedirectToSignUp) {\n const redirect = createRedirect({\n redirectAdapter,\n baseUrl: ternSecureRequest.ternUrl,\n signInUrl: SIGN_IN_URL,\n signUpUrl: SIGN_UP_URL,\n });\n\n const { returnBackUrl } = error;\n\n return redirect[isRedirectToSignIn ? 'redirectToSignIn' : 'redirectToSignUp']({\n returnBackUrl,\n });\n }\n\n if (isNextjsRedirectError(error)) {\n return redirectAdapter(error.redirectUrl);\n }\n\n throw error;\n};\n"],"mappings":"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","names":["request","event"]}
|
package/dist/esm/server/utils.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { constants } from "@tern-secure/backend";
|
|
2
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
3
|
+
import { constants as nextConstants } from "../constants";
|
|
4
|
+
const OVERRIDE_HEADERS = "x-middleware-override-headers";
|
|
5
|
+
const MIDDLEWARE_HEADER_PREFIX = "x-middleware-request";
|
|
1
6
|
const getGlobalObject = () => {
|
|
2
7
|
if (typeof process !== "undefined") {
|
|
3
8
|
return process;
|
|
@@ -78,7 +83,100 @@ class Store {
|
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
}
|
|
86
|
+
const setRequestHeadersOnNextResponse = (res, req, newHeaders) => {
|
|
87
|
+
if (!res.headers.get(OVERRIDE_HEADERS)) {
|
|
88
|
+
res.headers.set(OVERRIDE_HEADERS, [...req.headers.keys()]);
|
|
89
|
+
req.headers.forEach((val, key) => {
|
|
90
|
+
res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
Object.entries(newHeaders).forEach(([key, val]) => {
|
|
94
|
+
res.headers.set(OVERRIDE_HEADERS, `${res.headers.get(OVERRIDE_HEADERS)},${key}`);
|
|
95
|
+
res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
function decorateRequest(req, res, requestState) {
|
|
99
|
+
const { reason, token, status } = requestState;
|
|
100
|
+
if (!res) {
|
|
101
|
+
res = NextResponse.next();
|
|
102
|
+
}
|
|
103
|
+
if (res.headers.get(nextConstants.Headers.NextRedirect)) {
|
|
104
|
+
return res;
|
|
105
|
+
}
|
|
106
|
+
let rewriteURL;
|
|
107
|
+
if (res.headers.get(nextConstants.Headers.NextResume) === "1") {
|
|
108
|
+
res.headers.delete(nextConstants.Headers.NextResume);
|
|
109
|
+
rewriteURL = new URL(req.url);
|
|
110
|
+
}
|
|
111
|
+
const rewriteURLHeader = res.headers.get(nextConstants.Headers.NextRewrite);
|
|
112
|
+
if (rewriteURLHeader) {
|
|
113
|
+
const reqURL = new URL(req.url);
|
|
114
|
+
rewriteURL = new URL(rewriteURLHeader);
|
|
115
|
+
if (rewriteURL.origin !== reqURL.origin) {
|
|
116
|
+
return res;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (rewriteURL) {
|
|
120
|
+
setRequestHeadersOnNextResponse(res, req, {
|
|
121
|
+
[constants.Headers.AuthStatus]: status,
|
|
122
|
+
[constants.Headers.AuthToken]: token || "",
|
|
123
|
+
[constants.Headers.AuthReason]: reason || "",
|
|
124
|
+
[constants.Headers.TernSecureUrl]: req.ternUrl.toString()
|
|
125
|
+
});
|
|
126
|
+
res.headers.set(nextConstants.Headers.NextRewrite, rewriteURL.href);
|
|
127
|
+
}
|
|
128
|
+
return res;
|
|
129
|
+
}
|
|
130
|
+
const isPrerenderingBailout = (e) => {
|
|
131
|
+
if (!(e instanceof Error) || !("message" in e)) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
const { message } = e;
|
|
135
|
+
const lowerCaseInput = message.toLowerCase();
|
|
136
|
+
const dynamicServerUsage = lowerCaseInput.includes("dynamic server usage");
|
|
137
|
+
const bailOutPrerendering = lowerCaseInput.includes("this page needs to bail out of prerendering");
|
|
138
|
+
const routeRegex = /Route .*? needs to bail out of prerendering at this point because it used .*?./;
|
|
139
|
+
return routeRegex.test(message) || dynamicServerUsage || bailOutPrerendering;
|
|
140
|
+
};
|
|
141
|
+
async function buildRequestLike() {
|
|
142
|
+
try {
|
|
143
|
+
const { headers } = await import("next/headers");
|
|
144
|
+
const resolvedHeaders = await headers();
|
|
145
|
+
return new NextRequest("https://placeholder.com", { headers: resolvedHeaders });
|
|
146
|
+
} catch (e) {
|
|
147
|
+
if (e && isPrerenderingBailout(e)) {
|
|
148
|
+
throw e;
|
|
149
|
+
}
|
|
150
|
+
throw new Error(
|
|
151
|
+
`Clerk: auth(), currentUser() and clerkClient(), are only supported in App Router (/app directory).
|
|
152
|
+
If you're using /pages, try getAuth() instead.
|
|
153
|
+
Original error: ${e}`
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function getScriptNonceFromHeader(cspHeaderValue) {
|
|
158
|
+
const directives = cspHeaderValue.split(";").map((directive2) => directive2.trim());
|
|
159
|
+
const directive = directives.find((dir) => dir.startsWith("script-src")) || directives.find((dir) => dir.startsWith("default-src"));
|
|
160
|
+
if (!directive) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const nonce = directive.split(" ").slice(1).map((source) => source.trim()).find((source) => source.startsWith("'nonce-") && source.length > 8 && source.endsWith("'"))?.slice(7, -1);
|
|
164
|
+
if (!nonce) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (/[&><\u2028\u2029]/g.test(nonce)) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
"Nonce value from Content-Security-Policy contained invalid HTML escape characters, which is disallowed for security reasons. Make sure that your nonce value does not contain the following characters: `<`, `>`, `&`"
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
return nonce;
|
|
173
|
+
}
|
|
81
174
|
export {
|
|
82
|
-
Store
|
|
175
|
+
Store,
|
|
176
|
+
buildRequestLike,
|
|
177
|
+
decorateRequest,
|
|
178
|
+
getScriptNonceFromHeader,
|
|
179
|
+
isPrerenderingBailout,
|
|
180
|
+
setRequestHeadersOnNextResponse
|
|
83
181
|
};
|
|
84
182
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/utils.ts"],"sourcesContent":["import type { User } from \"./types\"\r\n\r\ninterface RequestContext {\r\n user: User\r\n sessionId: string\r\n}\r\n\r\n// Use process.env in Node.js and globalThis in Edge\r\nconst getGlobalObject = () => {\r\n if (typeof process !== 'undefined') {\r\n return process\r\n }\r\n return globalThis\r\n}\r\n\r\nconst STORE_KEY = '__TERN_AUTH_STORE__'\r\n\r\nexport class Store {\r\n private static getStore() {\r\n const global = getGlobalObject() as any\r\n \r\n if (!global[STORE_KEY]) {\r\n global[STORE_KEY] = {\r\n contexts: new Map<string, RequestContext>(),\r\n sessions: new Map<string, User>(),\r\n currentSession: null as RequestContext | null\r\n }\r\n }\r\n \r\n return global[STORE_KEY]\r\n }\r\n\r\n static setContext(context: RequestContext) {\r\n const store = this.getStore()\r\n const { user, sessionId } = context\r\n \r\n console.log(\"Store: Setting context:\", { sessionId, user })\r\n \r\n // Store in both maps\r\n store.contexts.set(sessionId, context)\r\n store.sessions.set(sessionId, user)\r\n \r\n // Set as current session\r\n store.currentSession = context\r\n \r\n console.log(\"Store: Updated state:\", {\r\n contextsSize: store.contexts.size,\r\n sessionsSize: store.sessions.size,\r\n currentSession: store.currentSession\r\n })\r\n }\r\n\r\n static getContext(): RequestContext | null {\r\n const store = this.getStore()\r\n \r\n // First try current session\r\n if (store.currentSession) {\r\n const session = this.getSession(store.currentSession.sessionId)\r\n if (session && session.uid === store.currentSession.user.uid) {\r\n return store.currentSession\r\n }\r\n }\r\n \r\n // Then try to find any valid context\r\n for (const [sessionId, user] of store.sessions.entries()) {\r\n const context = store.contexts.get(sessionId)\r\n if (context && context.user.uid === user.uid) {\r\n // Update current session\r\n store.currentSession = context\r\n return context\r\n }\r\n }\r\n \r\n return null\r\n }\r\n\r\n static setSession(sessionId: string, user: User) {\r\n const store = this.getStore()\r\n store.sessions.set(sessionId, user)\r\n }\r\n\r\n static getSession(sessionId: string): User | null {\r\n const store = this.getStore()\r\n return store.sessions.get(sessionId) || null\r\n }\r\n\r\n static debug() {\r\n const store = this.getStore()\r\n return {\r\n contextsSize: store.contexts.size,\r\n sessionsSize: store.sessions.size,\r\n currentSession: store.currentSession,\r\n contexts: Array.from(store.contexts.entries()),\r\n sessions: Array.from(store.sessions.entries())\r\n }\r\n }\r\n\r\n static cleanup() {\r\n const store = this.getStore()\r\n const MAX_ENTRIES = 1000\r\n \r\n if (store.contexts.size > MAX_ENTRIES) {\r\n const keys = Array.from(store.contexts.keys())\r\n const toDelete = keys.slice(0, keys.length - MAX_ENTRIES)\r\n \r\n toDelete.forEach(key => {\r\n store.contexts.delete(key)\r\n store.sessions.delete(key)\r\n })\r\n }\r\n }\r\n}"],"mappings":"AAQA,MAAM,kBAAkB,MAAM;AAC5B,MAAI,OAAO,YAAY,aAAa;AAClC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,MAAM,YAAY;AAEX,MAAM,MAAM;AAAA,EACjB,OAAe,WAAW;AACxB,UAAM,SAAS,gBAAgB;AAE/B,QAAI,CAAC,OAAO,SAAS,GAAG;AACtB,aAAO,SAAS,IAAI;AAAA,QAClB,UAAU,oBAAI,IAA4B;AAAA,QAC1C,UAAU,oBAAI,IAAkB;AAAA,QAChC,gBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA,EAEA,OAAO,WAAW,SAAyB;AACzC,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,EAAE,MAAM,UAAU,IAAI;AAE5B,YAAQ,IAAI,2BAA2B,EAAE,WAAW,KAAK,CAAC;AAG1D,UAAM,SAAS,IAAI,WAAW,OAAO;AACrC,UAAM,SAAS,IAAI,WAAW,IAAI;AAGlC,UAAM,iBAAiB;AAEvB,YAAQ,IAAI,yBAAyB;AAAA,MACnC,cAAc,MAAM,SAAS;AAAA,MAC7B,cAAc,MAAM,SAAS;AAAA,MAC7B,gBAAgB,MAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,aAAoC;AACzC,UAAM,QAAQ,KAAK,SAAS;AAG5B,QAAI,MAAM,gBAAgB;AACxB,YAAM,UAAU,KAAK,WAAW,MAAM,eAAe,SAAS;AAC9D,UAAI,WAAW,QAAQ,QAAQ,MAAM,eAAe,KAAK,KAAK;AAC5D,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAGA,eAAW,CAAC,WAAW,IAAI,KAAK,MAAM,SAAS,QAAQ,GAAG;AACxD,YAAM,UAAU,MAAM,SAAS,IAAI,SAAS;AAC5C,UAAI,WAAW,QAAQ,KAAK,QAAQ,KAAK,KAAK;AAE5C,cAAM,iBAAiB;AACvB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,WAAW,WAAmB,MAAY;AAC/C,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,SAAS,IAAI,WAAW,IAAI;AAAA,EACpC;AAAA,EAEA,OAAO,WAAW,WAAgC;AAChD,UAAM,QAAQ,KAAK,SAAS;AAC5B,WAAO,MAAM,SAAS,IAAI,SAAS,KAAK;AAAA,EAC1C;AAAA,EAEA,OAAO,QAAQ;AACb,UAAM,QAAQ,KAAK,SAAS;AAC5B,WAAO;AAAA,MACL,cAAc,MAAM,SAAS;AAAA,MAC7B,cAAc,MAAM,SAAS;AAAA,MAC7B,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM,KAAK,MAAM,SAAS,QAAQ,CAAC;AAAA,MAC7C,UAAU,MAAM,KAAK,MAAM,SAAS,QAAQ,CAAC;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,OAAO,UAAU;AACf,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,cAAc;AAEpB,QAAI,MAAM,SAAS,OAAO,aAAa;AACrC,YAAM,OAAO,MAAM,KAAK,MAAM,SAAS,KAAK,CAAC;AAC7C,YAAM,WAAW,KAAK,MAAM,GAAG,KAAK,SAAS,WAAW;AAExD,eAAS,QAAQ,SAAO;AACtB,cAAM,SAAS,OAAO,GAAG;AACzB,cAAM,SAAS,OAAO,GAAG;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/server/utils.ts"],"sourcesContent":["import type {\r\n RequestState,\r\n TernSecureRequest,\r\n} from \"@tern-secure/backend\";\r\nimport { constants } from \"@tern-secure/backend\";\r\nimport { NextRequest,NextResponse } from 'next/server';\r\n\r\nimport { constants as nextConstants } from \"../constants\";\r\nimport type { User } from \"./types\"\r\n\r\nconst OVERRIDE_HEADERS = 'x-middleware-override-headers';\r\nconst MIDDLEWARE_HEADER_PREFIX = 'x-middleware-request' as string;\r\n\r\ninterface RequestContext {\r\n user: User\r\n sessionId: string\r\n}\r\n\r\n// Use process.env in Node.js and globalThis in Edge\r\nconst getGlobalObject = () => {\r\n if (typeof process !== 'undefined') {\r\n return process\r\n }\r\n return globalThis\r\n}\r\n\r\nconst STORE_KEY = '__TERN_AUTH_STORE__'\r\n\r\nexport class Store {\r\n private static getStore() {\r\n const global = getGlobalObject() as any\r\n \r\n if (!global[STORE_KEY]) {\r\n global[STORE_KEY] = {\r\n contexts: new Map<string, RequestContext>(),\r\n sessions: new Map<string, User>(),\r\n currentSession: null as RequestContext | null\r\n }\r\n }\r\n \r\n return global[STORE_KEY]\r\n }\r\n\r\n static setContext(context: RequestContext) {\r\n const store = this.getStore()\r\n const { user, sessionId } = context\r\n \r\n console.log(\"Store: Setting context:\", { sessionId, user })\r\n \r\n // Store in both maps\r\n store.contexts.set(sessionId, context)\r\n store.sessions.set(sessionId, user)\r\n \r\n // Set as current session\r\n store.currentSession = context\r\n \r\n console.log(\"Store: Updated state:\", {\r\n contextsSize: store.contexts.size,\r\n sessionsSize: store.sessions.size,\r\n currentSession: store.currentSession\r\n })\r\n }\r\n\r\n static getContext(): RequestContext | null {\r\n const store = this.getStore()\r\n \r\n // First try current session\r\n if (store.currentSession) {\r\n const session = this.getSession(store.currentSession.sessionId)\r\n if (session && session.uid === store.currentSession.user.uid) {\r\n return store.currentSession\r\n }\r\n }\r\n \r\n // Then try to find any valid context\r\n for (const [sessionId, user] of store.sessions.entries()) {\r\n const context = store.contexts.get(sessionId)\r\n if (context && context.user.uid === user.uid) {\r\n // Update current session\r\n store.currentSession = context\r\n return context\r\n }\r\n }\r\n \r\n return null\r\n }\r\n\r\n static setSession(sessionId: string, user: User) {\r\n const store = this.getStore()\r\n store.sessions.set(sessionId, user)\r\n }\r\n\r\n static getSession(sessionId: string): User | null {\r\n const store = this.getStore()\r\n return store.sessions.get(sessionId) || null\r\n }\r\n\r\n static debug() {\r\n const store = this.getStore()\r\n return {\r\n contextsSize: store.contexts.size,\r\n sessionsSize: store.sessions.size,\r\n currentSession: store.currentSession,\r\n contexts: Array.from(store.contexts.entries()),\r\n sessions: Array.from(store.sessions.entries())\r\n }\r\n }\r\n\r\n static cleanup() {\r\n const store = this.getStore()\r\n const MAX_ENTRIES = 1000\r\n \r\n if (store.contexts.size > MAX_ENTRIES) {\r\n const keys = Array.from(store.contexts.keys())\r\n const toDelete = keys.slice(0, keys.length - MAX_ENTRIES)\r\n \r\n toDelete.forEach(key => {\r\n store.contexts.delete(key)\r\n store.sessions.delete(key)\r\n })\r\n }\r\n }\r\n}\r\n\r\n\r\nexport const setRequestHeadersOnNextResponse = (\r\n res: NextResponse | Response,\r\n req: Request,\r\n newHeaders: Record<string, string>,\r\n) => {\r\n if (!res.headers.get(OVERRIDE_HEADERS)) {\r\n // Emulate a user setting overrides by explicitly adding the required nextjs headers\r\n // https://github.com/vercel/next.js/pull/41380\r\n // @ts-expect-error -- property keys does not exist on type Headers\r\n res.headers.set(OVERRIDE_HEADERS, [...req.headers.keys()]);\r\n req.headers.forEach((val, key) => {\r\n res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);\r\n });\r\n }\r\n\r\n // Now that we have normalised res to include overrides, just append the new header\r\n Object.entries(newHeaders).forEach(([key, val]) => {\r\n res.headers.set(OVERRIDE_HEADERS, `${res.headers.get(OVERRIDE_HEADERS)},${key}`);\r\n res.headers.set(`${MIDDLEWARE_HEADER_PREFIX}-${key}`, val);\r\n });\r\n};\r\n\r\nexport function decorateRequest(\r\n req: TernSecureRequest,\r\n res: Response,\r\n requestState: RequestState,\r\n): Response {\r\n const { reason, token, status } = requestState;\r\n // pass-through case, convert to next()\r\n if (!res) {\r\n res = NextResponse.next();\r\n }\r\n\r\n // redirect() case, return early\r\n if (res.headers.get(nextConstants.Headers.NextRedirect)) {\r\n return res;\r\n }\r\n\r\n let rewriteURL;\r\n\r\n // next() case, convert to a rewrite\r\n if (res.headers.get(nextConstants.Headers.NextResume) === '1') {\r\n res.headers.delete(nextConstants.Headers.NextResume);\r\n rewriteURL = new URL(req.url);\r\n }\r\n\r\n // rewrite() case, set auth result only if origin remains the same\r\n const rewriteURLHeader = res.headers.get(nextConstants.Headers.NextRewrite);\r\n\r\n if (rewriteURLHeader) {\r\n const reqURL = new URL(req.url);\r\n rewriteURL = new URL(rewriteURLHeader);\r\n\r\n // if the origin has changed, return early\r\n if (rewriteURL.origin !== reqURL.origin) {\r\n return res;\r\n }\r\n }\r\n\r\n if (rewriteURL) {\r\n setRequestHeadersOnNextResponse(res, req, {\r\n [constants.Headers.AuthStatus]: status,\r\n [constants.Headers.AuthToken]: token || '',\r\n [constants.Headers.AuthReason]: reason || '',\r\n [constants.Headers.TernSecureUrl]: req.ternUrl.toString(),\r\n });\r\n res.headers.set(nextConstants.Headers.NextRewrite, rewriteURL.href);\r\n }\r\n\r\n return res;\r\n}\r\n\r\n\r\nexport const isPrerenderingBailout = (e: unknown) => {\r\n if (!(e instanceof Error) || !('message' in e)) {\r\n return false;\r\n }\r\n\r\n const { message } = e;\r\n\r\n const lowerCaseInput = message.toLowerCase();\r\n const dynamicServerUsage = lowerCaseInput.includes('dynamic server usage');\r\n const bailOutPrerendering = lowerCaseInput.includes('this page needs to bail out of prerendering');\r\n\r\n // note: new error message syntax introduced in next@14.1.1-canary.21\r\n // but we still want to support older versions.\r\n // https://github.com/vercel/next.js/pull/61332 (dynamic-rendering.ts:153)\r\n const routeRegex = /Route .*? needs to bail out of prerendering at this point because it used .*?./;\r\n\r\n return routeRegex.test(message) || dynamicServerUsage || bailOutPrerendering;\r\n};\r\n\r\nexport async function buildRequestLike(): Promise<NextRequest> {\r\n try {\r\n // Dynamically import next/headers, otherwise Next12 apps will break\r\n // @ts-expect-error: Cannot find module 'next/headers' or its corresponding type declarations.ts(2307)\r\n const { headers } = await import('next/headers');\r\n const resolvedHeaders = await headers();\r\n return new NextRequest('https://placeholder.com', { headers: resolvedHeaders });\r\n } catch (e: any) {\r\n // rethrow the error when react throws a prerendering bailout\r\n // https://nextjs.org/docs/messages/ppr-caught-error\r\n if (e && isPrerenderingBailout(e)) {\r\n throw e;\r\n }\r\n\r\n throw new Error(\r\n `Clerk: auth(), currentUser() and clerkClient(), are only supported in App Router (/app directory).\\nIf you're using /pages, try getAuth() instead.\\nOriginal error: ${e}`,\r\n );\r\n }\r\n}\r\n\r\n// Original source: https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/get-script-nonce-from-header.tsx\r\nexport function getScriptNonceFromHeader(cspHeaderValue: string): string | undefined {\r\n const directives = cspHeaderValue\r\n // Directives are split by ';'.\r\n .split(';')\r\n .map(directive => directive.trim());\r\n\r\n // First try to find the directive for the 'script-src', otherwise try to\r\n // fallback to the 'default-src'.\r\n const directive =\r\n directives.find(dir => dir.startsWith('script-src')) || directives.find(dir => dir.startsWith('default-src'));\r\n\r\n // If no directive could be found, then we're done.\r\n if (!directive) {\r\n return;\r\n }\r\n\r\n // Extract the nonce from the directive\r\n const nonce = directive\r\n .split(' ')\r\n // Remove the 'strict-src'/'default-src' string, this can't be the nonce.\r\n .slice(1)\r\n .map(source => source.trim())\r\n // Find the first source with the 'nonce-' prefix.\r\n .find(source => source.startsWith(\"'nonce-\") && source.length > 8 && source.endsWith(\"'\"))\r\n // Grab the nonce by trimming the 'nonce-' prefix.\r\n ?.slice(7, -1);\r\n\r\n // If we couldn't find the nonce, then we're done.\r\n if (!nonce) {\r\n return;\r\n }\r\n\r\n // Don't accept the nonce value if it contains HTML escape characters.\r\n // Technically, the spec requires a base64'd value, but this is just an\r\n // extra layer.\r\n if (/[&><\\u2028\\u2029]/g.test(nonce)) {\r\n throw new Error(\r\n 'Nonce value from Content-Security-Policy contained invalid HTML escape characters, which is disallowed for security reasons. Make sure that your nonce value does not contain the following characters: `<`, `>`, `&`',\r\n );\r\n }\r\n\r\n return nonce;\r\n}\r\n"],"mappings":"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","names":["directive"]}
|
package/dist/esm/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../src/types.ts"],"sourcesContent":["import type { TernSecureProviderProps } from '@tern-secure/react'\r\n\r\nimport type { ERRORS } from './errors'\r\n\r\n\r\n/**\r\n * TernSecure User\r\n */\r\n//export type TernSecureUser = FirebaseUser\r\n\r\nexport type TernSecureUserData = {\r\n uid: string\r\n email: string | null\r\n emailVerified?: boolean\r\n displayName?: string | null\r\n}\r\n\r\n\r\n/**\r\n * TernSecure Firebase configuration interface\r\n * Extends Firebase's base configuration options\r\n */\r\n//export interface TernSecureConfig extends FirebaseOptions {\r\n// apiKey: string\r\n// authDomain: string\r\n// projectId: string\r\n// storageBucket: string\r\n// messagingSenderId: string\r\n// appId: string\r\n// measurementId?: string // Optional for analytics\r\n//}\r\n\r\n/**\r\n * TernSecure initialization options\r\n */\r\nexport interface TernSecureOptions {\r\n /** Environment setting for different configurations */\r\n environment?: 'development' | 'production'\r\n /** Geographic region for data storage */\r\n region?: string\r\n /** Custom error handler */\r\n onError?: (error: Error) => void\r\n /** Debug mode flag */\r\n debug?: boolean\r\n}\r\n\r\n/**\r\n * Firebase initialization state\r\n */\r\nexport interface FirebaseState {\r\n /** Whether Firebase has been initialized */\r\n initialized: boolean\r\n /** Any initialization errors */\r\n error: Error | null\r\n /** Timestamp of last initialization attempt */\r\n lastInitAttempt?: number\r\n}\r\n\r\n/**\r\n * Configuration validation result\r\n */\r\nexport interface ConfigValidationResult {\r\n isValid: boolean\r\n errors: string[]\r\n //config: TernSecureConfig\r\n}\r\n\r\n/**\r\n * Firebase Admin configuration interface\r\n */\r\nexport interface TernSecureAdminConfig {\r\n projectId: string\r\n clientEmail: string\r\n privateKey: string\r\n}\r\n\r\n/**\r\n * Firebase Admin configuration validation result\r\n */\r\nexport interface AdminConfigValidationResult {\r\n isValid: boolean\r\n errors: string[]\r\n config: TernSecureAdminConfig\r\n}\r\n\r\n\r\nexport interface SignInResponse {\r\n success: boolean;\r\n message?: string;\r\n error?: keyof typeof ERRORS | undefined; \r\n user?: any;\r\n}\r\n\r\nexport interface AuthError extends Error {\r\n code?: string\r\n message: string\r\n response?: SignInResponse\r\n}\r\n\r\nexport function isSignInResponse(value: any): value is SignInResponse {\r\n return typeof value === \"object\" && \"success\" in value && typeof value.success === \"boolean\"\r\n}\r\n\r\n\r\nexport interface TernSecureState {\r\n userId: string | null\r\n isLoaded: boolean\r\n error: Error | null\r\n isValid: boolean\r\n isVerified: boolean\r\n isAuthenticated: boolean\r\n token: any | null\r\n email: string | null\r\n status: \"loading\" | \"authenticated\" | \"unauthenticated\" | \"unverified\"\r\n requiresVerification: boolean\r\n}\r\n\r\nexport interface RedirectConfig {\r\n // URL to redirect to after successful authentication\r\n redirectUrl?: string\r\n // Whether this is a return visit (e.g. after sign out)\r\n isReturn?: boolean\r\n // Priority of the redirect (higher number = higher priority)\r\n priority?: number\r\n}\r\n\r\n\r\nexport interface SignInProps extends RedirectConfig {\r\n onError?: (error: Error) => void\r\n onSuccess?: () => void\r\n className?: string\r\n customStyles?: {\r\n card?: string\r\n input?: string\r\n button?: string\r\n label?: string\r\n separator?: string\r\n title?: string\r\n description?: string\r\n socialButton?: string\r\n }\r\n}\r\n\r\n\r\nexport type TernSecureNextProps = TernSecureProviderProps & {\r\n apiKey?: string\r\n requiresVerification?: boolean\r\n loadingComponent?: React.ReactNode\r\n}\r\n\r\nexport interface User {\r\n uid: string\r\n email: string | null\r\n emailVerified?: boolean\r\n authTime?: number\r\n disabled?: boolean\r\n}\r\n\r\nexport interface BaseUser {\r\n uid: string\r\n email: string | null\r\n emailVerified?: boolean\r\n tenantId: string | null\r\n authTime?: number\r\n}\r\n \r\n\r\n\r\n export interface UserInfo {\r\n uid: string\r\n email: string | null\r\n emailVerified?: boolean\r\n authTime?: number\r\n disabled?: boolean\r\n }\r\n \r\n export interface SessionUser {\r\n uid: string\r\n email: string | null\r\n emailVerified: boolean\r\n disabled?: boolean\r\n }\r\n \r\n export interface SessionResult {\r\n isAuthenticated: boolean\r\n user: UserInfo | null\r\n error?: string\r\n }\r\n\r\n\r\n"],"mappings":"AAmGO,SAAS,iBAAiB,OAAqC;AACpE,SAAO,OAAO,UAAU,YAAY,aAAa,SAAS,OAAO,MAAM,YAAY;AACrF;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { cookies } from "next/headers";
|
|
2
|
+
class NextCookieStore {
|
|
3
|
+
async get(name) {
|
|
4
|
+
const cookieStore = await cookies();
|
|
5
|
+
const cookie = cookieStore.get(name);
|
|
6
|
+
return { value: cookie?.value };
|
|
7
|
+
}
|
|
8
|
+
async set(name, value, options) {
|
|
9
|
+
const cookieStore = await cookies();
|
|
10
|
+
cookieStore.set(name, value, options);
|
|
11
|
+
}
|
|
12
|
+
async delete(name) {
|
|
13
|
+
const cookieStore = await cookies();
|
|
14
|
+
cookieStore.delete(name);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
NextCookieStore
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=NextCookieAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/NextCookieAdapter.ts"],"sourcesContent":["import type { CookieOptions,CookieStore } from '@tern-secure/types';\nimport { cookies } from 'next/headers';\n\nexport class NextCookieStore implements CookieStore {\n async get(name: string): Promise<{ value: string | undefined }> {\n const cookieStore = await cookies();\n const cookie = cookieStore.get(name);\n return { value: cookie?.value };\n }\n\n async set(name: string, value: string, options: CookieOptions): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(name, value, options);\n }\n\n async delete(name: string): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.delete(name);\n }\n}"],"mappings":"AACA,SAAS,eAAe;AAEjB,MAAM,gBAAuC;AAAA,EAClD,MAAM,IAAI,MAAsD;AAC9D,UAAM,cAAc,MAAM,QAAQ;AAClC,UAAM,SAAS,YAAY,IAAI,IAAI;AACnC,WAAO,EAAE,OAAO,QAAQ,MAAM;AAAA,EAChC;AAAA,EAEA,MAAM,IAAI,MAAc,OAAe,SAAuC;AAC5E,UAAM,cAAc,MAAM,QAAQ;AAClC,gBAAY,IAAI,MAAM,OAAO,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,OAAO,MAA6B;AACxC,UAAM,cAAc,MAAM,QAAQ;AAClC,gBAAY,OAAO,IAAI;AAAA,EACzB;AACF;","names":[]}
|
|
@@ -2,12 +2,8 @@ const allNextProviderPropsWithEnv = (nextProps) => {
|
|
|
2
2
|
const {
|
|
3
3
|
signInUrl,
|
|
4
4
|
signUpUrl,
|
|
5
|
-
signInForceRedirectUrl: propsSignInForceRedirectUrl,
|
|
6
|
-
signUpForceRedirectUrl: propsSignUpForceRedirectUrl,
|
|
7
5
|
apiKey: propsApiKey,
|
|
8
|
-
|
|
9
|
-
customDomain: propsCustomDomain,
|
|
10
|
-
proxyUrl: propsProxyUrl,
|
|
6
|
+
apiUrl: propsApiUrl,
|
|
11
7
|
requiresVerification: propsRequiresVerification,
|
|
12
8
|
isTernSecureDev: propsIsTernSecureDev,
|
|
13
9
|
enableServiceWorker: propsEnableServiceWorker,
|
|
@@ -16,14 +12,15 @@ const allNextProviderPropsWithEnv = (nextProps) => {
|
|
|
16
12
|
} = nextProps;
|
|
17
13
|
const envConfig = {
|
|
18
14
|
apiKey: process.env.NEXT_PUBLIC_TERN_API_KEY,
|
|
15
|
+
apiUrl: process.env.TERNSECURE_API_URL || "",
|
|
19
16
|
projectId: process.env.NEXT_PUBLIC_TERN_PROJECT_ID,
|
|
20
17
|
customDomain: process.env.NEXT_PUBLIC_TERN_CUSTOM_DOMAIN,
|
|
21
18
|
proxyUrl: process.env.NEXT_PUBLIC_TERN_PROXY_URL,
|
|
22
19
|
environment: process.env.NEXT_PUBLIC_TERN_ENVIRONMENT,
|
|
23
20
|
signInUrl: process.env.NEXT_PUBLIC_SIGN_IN_URL,
|
|
24
21
|
signUpUrl: process.env.NEXT_PUBLIC_SIGN_UP_URL,
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
persistence: process.env.NEXT_PUBLIC_TERN_PERSISTENCE,
|
|
23
|
+
useEmulator: process.env.NEXT_PUBLIC_USE_FIREBASE_EMULATOR,
|
|
27
24
|
projectIdAdmin: process.env.FIREBASE_PROJECT_ID,
|
|
28
25
|
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
|
|
29
26
|
privateKey: process.env.FIREBASE_PRIVATE_KEY
|
|
@@ -36,23 +33,16 @@ const allNextProviderPropsWithEnv = (nextProps) => {
|
|
|
36
33
|
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || "",
|
|
37
34
|
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || "",
|
|
38
35
|
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || "",
|
|
39
|
-
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENTID
|
|
36
|
+
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENTID,
|
|
37
|
+
tenantId: process.env.NEXT_PUBLIC_FIREBASE_TENANT_ID || ""
|
|
40
38
|
};
|
|
41
39
|
const finalApiKey = propsApiKey ?? envConfig.apiKey;
|
|
42
|
-
const
|
|
43
|
-
const finalCustomDomain = propsCustomDomain ?? envConfig.customDomain;
|
|
44
|
-
const finalProxyUrl = propsProxyUrl ?? envConfig.proxyUrl;
|
|
40
|
+
const finalApiUrl = propsApiUrl ?? envConfig.apiUrl;
|
|
45
41
|
const finalSignInUrl = signInUrl ?? envConfig.signInUrl;
|
|
46
42
|
const finalSignUpUrl = signUpUrl ?? envConfig.signUpUrl;
|
|
47
|
-
const
|
|
48
|
-
const finalSignUpForceRedirectUrl = propsSignUpForceRedirectUrl ?? envConfig.signUpForceRedirectUrl;
|
|
43
|
+
const finalPersistence = baseProps.persistence ?? envConfig.persistence;
|
|
49
44
|
const result = {
|
|
50
45
|
...baseProps,
|
|
51
|
-
// Set the merged/prioritized instance configuration properties
|
|
52
|
-
apiKey: finalApiKey,
|
|
53
|
-
projectId: finalProjectId,
|
|
54
|
-
customDomain: finalCustomDomain,
|
|
55
|
-
proxyUrl: finalProxyUrl,
|
|
56
46
|
// Set the Firebase configuration properties
|
|
57
47
|
ternSecureConfig,
|
|
58
48
|
// Set properties explicitly taken from TernSecureNextProps (props version)
|
|
@@ -64,15 +54,11 @@ const allNextProviderPropsWithEnv = (nextProps) => {
|
|
|
64
54
|
//TernSecure: baseProps.Instance,
|
|
65
55
|
initialState: baseProps.initialState,
|
|
66
56
|
bypassApiKey: baseProps.bypassApiKey,
|
|
67
|
-
initialSession: baseProps.initialSession,
|
|
68
|
-
defaultAppearance: baseProps.defaultAppearance,
|
|
69
57
|
signInUrl: finalSignInUrl,
|
|
70
58
|
signUpUrl: finalSignUpUrl,
|
|
71
|
-
signInForceRedirectUrl: finalSignInForceRedirectUrl,
|
|
72
|
-
signUpForceRedirectUrl: finalSignUpForceRedirectUrl,
|
|
73
59
|
mode: baseProps.mode,
|
|
74
|
-
|
|
75
|
-
|
|
60
|
+
apiUrl: finalApiUrl,
|
|
61
|
+
persistence: finalPersistence
|
|
76
62
|
};
|
|
77
63
|
Object.keys(result).forEach((key) => {
|
|
78
64
|
if (result[key] === void 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/allNextProviderProps.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/allNextProviderProps.ts"],"sourcesContent":["import type { \n IsoTernSecureAuthOptions,\n TernSecureProviderProps} from \"@tern-secure/react\";\n\nimport type { TernSecureNextProps } from \"../types\";\n\n// Helper type for the return value, as children are handled by the consuming component\ntype NextProviderProcessedProps = Omit<TernSecureProviderProps, 'children'>;\n\nexport const allNextProviderPropsWithEnv = (\n nextProps: Omit<TernSecureNextProps, 'children'>\n): NextProviderProcessedProps => {\n const {\n signInUrl,\n signUpUrl,\n apiKey: propsApiKey,\n apiUrl: propsApiUrl,\n requiresVerification: propsRequiresVerification,\n isTernSecureDev: propsIsTernSecureDev,\n enableServiceWorker: propsEnableServiceWorker,\n loadingComponent: propsLoadingComponent,\n ...baseProps \n } = nextProps;\n\n const envConfig = {\n apiKey: process.env.NEXT_PUBLIC_TERN_API_KEY,\n apiUrl: process.env.TERNSECURE_API_URL || '',\n projectId: process.env.NEXT_PUBLIC_TERN_PROJECT_ID,\n customDomain: process.env.NEXT_PUBLIC_TERN_CUSTOM_DOMAIN,\n proxyUrl: process.env.NEXT_PUBLIC_TERN_PROXY_URL,\n environment: process.env.NEXT_PUBLIC_TERN_ENVIRONMENT,\n signInUrl: process.env.NEXT_PUBLIC_SIGN_IN_URL,\n signUpUrl: process.env.NEXT_PUBLIC_SIGN_UP_URL,\n persistence: process.env.NEXT_PUBLIC_TERN_PERSISTENCE as 'local' | 'session' | 'none',\n useEmulator: process.env.NEXT_PUBLIC_USE_FIREBASE_EMULATOR,\n projectIdAdmin: process.env.FIREBASE_PROJECT_ID,\n clientEmail: process.env.FIREBASE_CLIENT_EMAIL,\n privateKey: process.env.FIREBASE_PRIVATE_KEY,\n };\n\n const ternSecureConfig = {\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\n appName: process.env.NEXT_PUBLIC_FIREBASE_APP_NAME || '',\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENTID,\n tenantId: process.env.NEXT_PUBLIC_FIREBASE_TENANT_ID || '',\n };\n\n // Merge config values: props take precedence over environment variables\n const finalApiKey = propsApiKey ?? envConfig.apiKey;\n const finalApiUrl = propsApiUrl ?? envConfig.apiUrl;\n const finalSignInUrl = signInUrl ?? envConfig.signInUrl;\n const finalSignUpUrl = signUpUrl ?? envConfig.signUpUrl;\n const finalPersistence = baseProps.persistence ?? envConfig.persistence;\n\n // Construct the result, ensuring it conforms to NextProviderProcessedProps\n // (Omit<TernSecureProviderProps, 'children'>)\n const result: NextProviderProcessedProps = {\n ...(baseProps as Omit<TernSecureProviderProps, 'children' | keyof IsoTernSecureAuthOptions | 'requiresVerification' | 'loadingComponent'>),\n\n // Set the Firebase configuration properties\n ternSecureConfig,\n \n // Set properties explicitly taken from TernSecureNextProps (props version)\n // These are part of the TernSecureProviderProps interface.\n requiresVerification: propsRequiresVerification,\n isTernSecureDev: propsIsTernSecureDev,\n enableServiceWorker: propsEnableServiceWorker,\n loadingComponent: propsLoadingComponent,\n\n //TernSecure: baseProps.Instance,\n initialState: baseProps.initialState,\n bypassApiKey: baseProps.bypassApiKey,\n signInUrl: finalSignInUrl,\n signUpUrl: finalSignUpUrl,\n mode: baseProps.mode,\n apiUrl: finalApiUrl,\n persistence: finalPersistence\n };\n\n // Clean up undefined keys that might have resulted from spreading if not present in baseProps\n // and also not set by merged values (e.g. if env var is also undefined)\n Object.keys(result).forEach(key => {\n if (result[key as keyof NextProviderProcessedProps] === undefined) {\n delete result[key as keyof NextProviderProcessedProps];\n }\n });\n\n return result;\n};"],"mappings":"AASO,MAAM,8BAA8B,CACzC,cAC+B;AAC/B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,YAAY;AAAA,IAChB,QAAQ,QAAQ,IAAI;AAAA,IACpB,QAAQ,QAAQ,IAAI,sBAAsB;AAAA,IAC1C,WAAW,QAAQ,IAAI;AAAA,IACvB,cAAc,QAAQ,IAAI;AAAA,IAC1B,UAAU,QAAQ,IAAI;AAAA,IACtB,aAAa,QAAQ,IAAI;AAAA,IACzB,WAAW,QAAQ,IAAI;AAAA,IACvB,WAAW,QAAQ,IAAI;AAAA,IACvB,aAAa,QAAQ,IAAI;AAAA,IACzB,aAAa,QAAQ,IAAI;AAAA,IACzB,gBAAgB,QAAQ,IAAI;AAAA,IAC5B,aAAa,QAAQ,IAAI;AAAA,IACzB,YAAY,QAAQ,IAAI;AAAA,EAC1B;AAEA,QAAM,mBAAmB;AAAA,IACvB,QAAQ,QAAQ,IAAI,gCAAgC;AAAA,IACpD,YAAY,QAAQ,IAAI,oCAAoC;AAAA,IAC5D,SAAS,QAAQ,IAAI,iCAAiC;AAAA,IACtD,WAAW,QAAQ,IAAI,mCAAmC;AAAA,IAC1D,eAAe,QAAQ,IAAI,uCAAuC;AAAA,IAClE,mBAAmB,QAAQ,IAAI,4CAA4C;AAAA,IAC3E,OAAO,QAAQ,IAAI,+BAA+B;AAAA,IAClD,eAAe,QAAQ,IAAI;AAAA,IAC3B,UAAU,QAAQ,IAAI,kCAAkC;AAAA,EAC1D;AAGA,QAAM,cAAc,eAAe,UAAU;AAC7C,QAAM,cAAc,eAAe,UAAU;AAC7C,QAAM,iBAAiB,aAAa,UAAU;AAC9C,QAAM,iBAAiB,aAAa,UAAU;AAC9C,QAAM,mBAAmB,UAAU,eAAe,UAAU;AAI5D,QAAM,SAAqC;AAAA,IACzC,GAAI;AAAA;AAAA,IAGJ;AAAA;AAAA;AAAA,IAIA,sBAAsB;AAAA,IACtB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA;AAAA,IAGlB,cAAc,UAAU;AAAA,IACxB,cAAc,UAAU;AAAA,IACxB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,MAAM,UAAU;AAAA,IAChB,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAIA,SAAO,KAAK,MAAM,EAAE,QAAQ,SAAO;AACjC,QAAI,OAAO,GAAuC,MAAM,QAAW;AACjE,aAAO,OAAO,GAAuC;AAAA,IACvD;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":[]}
|
package/dist/esm/utils/config.js
CHANGED
|
@@ -73,12 +73,45 @@ ${validationResult.errors.join("\n")}`
|
|
|
73
73
|
}
|
|
74
74
|
return config;
|
|
75
75
|
};
|
|
76
|
+
const loadServerConfig = () => ({
|
|
77
|
+
apiKey: process.env.FIREBASE_SERVER_API_KEY || ""
|
|
78
|
+
});
|
|
79
|
+
const validateServerConfig = (config) => {
|
|
80
|
+
const requiredFields = [
|
|
81
|
+
"apiKey"
|
|
82
|
+
];
|
|
83
|
+
const errors = [];
|
|
84
|
+
requiredFields.forEach((field) => {
|
|
85
|
+
if (!config[field]) {
|
|
86
|
+
errors.push(`Missing required field: FIREBASE_SERVER_${String(field).toUpperCase()}`);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
isValid: errors.length === 0,
|
|
91
|
+
errors,
|
|
92
|
+
config
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const initializeServerConfig = () => {
|
|
96
|
+
const config = loadServerConfig();
|
|
97
|
+
const validationResult = validateServerConfig(config);
|
|
98
|
+
if (!validationResult.isValid) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Firebase Server configuration validation failed:
|
|
101
|
+
${validationResult.errors.join("\n")}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return config;
|
|
105
|
+
};
|
|
76
106
|
export {
|
|
77
107
|
initializeAdminConfig,
|
|
78
108
|
initializeConfig,
|
|
109
|
+
initializeServerConfig,
|
|
79
110
|
loadAdminConfig,
|
|
80
111
|
loadFireConfig,
|
|
112
|
+
loadServerConfig,
|
|
81
113
|
validateAdminConfig,
|
|
82
|
-
validateConfig
|
|
114
|
+
validateConfig,
|
|
115
|
+
validateServerConfig
|
|
83
116
|
};
|
|
84
117
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/config.ts"],"sourcesContent":["import { \r\n
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/config.ts"],"sourcesContent":["import type { \r\n AdminConfigValidationResult,\r\n ConfigValidationResult, \r\n ServerConfigValidationResult,\r\n TernSecureAdminConfig,\r\n TernSecureConfig, \r\n TernSecureServerConfig} from '@tern-secure/types'\r\n\r\n/**\r\n * Loads Firebase configuration from environment variables\r\n * @returns {TernSecureConfig} Firebase configuration object\r\n */\r\nexport const loadFireConfig = (): TernSecureConfig => ({\r\n apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || '',\r\n authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || '',\r\n projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || '',\r\n storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || '',\r\n messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || '',\r\n appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || '',\r\n measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID || undefined,\r\n})\r\n\r\n/**\r\n * Validates Firebase configuration\r\n * @param {TernSecureConfig} config - Firebase configuration object\r\n * @throws {Error} If required configuration values are missing\r\n * @returns {TernSecureConfig} Validated configuration object\r\n */\r\nexport const validateConfig = (config: TernSecureConfig): ConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureConfig)[] = [\r\n 'apiKey',\r\n 'authDomain',\r\n 'projectId',\r\n 'storageBucket',\r\n 'messagingSenderId',\r\n 'appId'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: NEXT_PUBLIC_FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeConfig = (): TernSecureConfig => {\r\n const config = loadFireConfig()\r\n const validationResult = validateConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}\r\n\r\n/**\r\n * Loads Firebase Admin configuration from environment variables\r\n * @returns {AdminConfig} Firebase Admin configuration object\r\n */\r\nexport const loadAdminConfig = (): TernSecureAdminConfig => ({\r\n projectId: process.env.FIREBASE_PROJECT_ID || '',\r\n clientEmail: process.env.FIREBASE_CLIENT_EMAIL || '',\r\n privateKey: process.env.FIREBASE_PRIVATE_KEY || '',\r\n})\r\n\r\n/**\r\n * Validates Firebase Admin configuration\r\n * @param {AdminConfig} config - Firebase Admin configuration object\r\n * @returns {ConfigValidationResult} Validation result\r\n */\r\nexport const validateAdminConfig = (config: TernSecureAdminConfig): AdminConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureAdminConfig)[] = [\r\n 'projectId',\r\n 'clientEmail',\r\n 'privateKey'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: FIREBASE_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n/**\r\n * Initializes admin configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeAdminConfig = (): TernSecureAdminConfig => {\r\n const config = loadAdminConfig()\r\n const validationResult = validateAdminConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase Admin configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}\r\n\r\n\r\n\r\n/**\r\n * Loads Firebase Server configuration from environment variables\r\n * @returns {ServerConfig} Firebase Server configuration object\r\n */\r\nexport const loadServerConfig = (): TernSecureServerConfig => ({\r\n apiKey: process.env.FIREBASE_SERVER_API_KEY || '',\r\n\r\n})\r\n\r\n\r\n/**\r\n * Validates Firebase Admin configuration\r\n * @param {AdminConfig} config - Firebase Admin configuration object\r\n * @returns {ConfigValidationResult} Validation result\r\n */\r\nexport const validateServerConfig = (config: TernSecureServerConfig): ServerConfigValidationResult => {\r\n const requiredFields: (keyof TernSecureServerConfig)[] = [\r\n 'apiKey'\r\n ]\r\n\r\n const errors: string[] = []\r\n \r\n requiredFields.forEach(field => {\r\n if (!config[field]) {\r\n errors.push(`Missing required field: FIREBASE_SERVER_${String(field).toUpperCase()}`)\r\n }\r\n })\r\n\r\n return {\r\n isValid: errors.length === 0,\r\n errors,\r\n config\r\n }\r\n}\r\n\r\n\r\n\r\n/**\r\n * Initializes admin configuration with validation\r\n * @throws {Error} If configuration is invalid\r\n */\r\nexport const initializeServerConfig = (): TernSecureServerConfig => {\r\n const config = loadServerConfig()\r\n const validationResult = validateServerConfig(config)\r\n\r\n if (!validationResult.isValid) {\r\n throw new Error(\r\n `Firebase Server configuration validation failed:\\n${validationResult.errors.join('\\n')}`\r\n )\r\n }\r\n\r\n return config\r\n}"],"mappings":"AAYO,MAAM,iBAAiB,OAAyB;AAAA,EACrD,QAAQ,QAAQ,IAAI,gCAAgC;AAAA,EACpD,YAAY,QAAQ,IAAI,oCAAoC;AAAA,EAC5D,WAAW,QAAQ,IAAI,mCAAmC;AAAA,EAC1D,eAAe,QAAQ,IAAI,uCAAuC;AAAA,EAClE,mBAAmB,QAAQ,IAAI,4CAA4C;AAAA,EAC3E,OAAO,QAAQ,IAAI,+BAA+B;AAAA,EAClD,eAAe,QAAQ,IAAI,uCAAuC;AACpE;AAQO,MAAM,iBAAiB,CAAC,WAAqD;AAClF,QAAM,iBAA6C;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAAmB,CAAC;AAE1B,iBAAe,QAAQ,WAAS;AAC9B,QAAI,CAAC,OAAO,KAAK,GAAG;AAClB,aAAO,KAAK,gDAAgD,OAAO,KAAK,EAAE,YAAY,CAAC,EAAE;AAAA,IAC3F;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,SAAS,OAAO,WAAW;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AACF;AAMO,MAAM,mBAAmB,MAAwB;AACtD,QAAM,SAAS,eAAe;AAC9B,QAAM,mBAAmB,eAAe,MAAM;AAE9C,MAAI,CAAC,iBAAiB,SAAS;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,EAA8C,iBAAiB,OAAO,KAAK,IAAI,CAAC;AAAA,IAClF;AAAA,EACF;AAEA,SAAO;AACT;AAMO,MAAM,kBAAkB,OAA8B;AAAA,EAC3D,WAAW,QAAQ,IAAI,uBAAuB;AAAA,EAC9C,aAAa,QAAQ,IAAI,yBAAyB;AAAA,EAClD,YAAY,QAAQ,IAAI,wBAAwB;AAClD;AAOO,MAAM,sBAAsB,CAAC,WAA+D;AACjG,QAAM,iBAAkD;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAAmB,CAAC;AAE1B,iBAAe,QAAQ,WAAS;AAC9B,QAAI,CAAC,OAAO,KAAK,GAAG;AAClB,aAAO,KAAK,oCAAoC,OAAO,KAAK,EAAE,YAAY,CAAC,EAAE;AAAA,IAC/E;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,SAAS,OAAO,WAAW;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AACF;AAMO,MAAM,wBAAwB,MAA6B;AAChE,QAAM,SAAS,gBAAgB;AAC/B,QAAM,mBAAmB,oBAAoB,MAAM;AAEnD,MAAI,CAAC,iBAAiB,SAAS;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,EAAoD,iBAAiB,OAAO,KAAK,IAAI,CAAC;AAAA,IACxF;AAAA,EACF;AAEA,SAAO;AACT;AAQO,MAAM,mBAAmB,OAA+B;AAAA,EAC7D,QAAQ,QAAQ,IAAI,2BAA2B;AAEjD;AAQO,MAAM,uBAAuB,CAAC,WAAiE;AACpG,QAAM,iBAAmD;AAAA,IACvD;AAAA,EACF;AAEA,QAAM,SAAmB,CAAC;AAE1B,iBAAe,QAAQ,WAAS;AAC9B,QAAI,CAAC,OAAO,KAAK,GAAG;AAClB,aAAO,KAAK,2CAA2C,OAAO,KAAK,EAAE,YAAY,CAAC,EAAE;AAAA,IACtF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,SAAS,OAAO,WAAW;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AACF;AAQO,MAAM,yBAAyB,MAA8B;AAClE,QAAM,SAAS,iBAAiB;AAChC,QAAM,mBAAmB,qBAAqB,MAAM;AAEpD,MAAI,CAAC,iBAAiB,SAAS;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,EAAqD,iBAAiB,OAAO,KAAK,IAAI,CAAC;AAAA,IACzF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isAuthRoute, isInternalRoute } from "../app-router/route-handler/internal-route";
|
|
2
2
|
const constructFullUrl = (path) => {
|
|
3
3
|
if (typeof window === "undefined") return path;
|
|
4
4
|
const baseUrl = window.location.origin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/construct.ts"],"sourcesContent":["//v2: redict with taking priority from the sign-in page\r\n\r\nimport { isInternalRoute
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/construct.ts"],"sourcesContent":["//v2: redict with taking priority from the sign-in page\r\n\r\nimport { isAuthRoute,isInternalRoute } from \"../app-router/route-handler/internal-route\"\r\n\r\n/**\r\n * Constructs a full URL with the current origin\r\n * @param path - The path to construct the URL for\r\n * @returns The full URL with origin\r\n */\r\nexport const constructFullUrl = (path: string) => {\r\n if (typeof window === \"undefined\") return path\r\n const baseUrl = window.location.origin\r\n if (path.startsWith('http')) {\r\n return path\r\n }\r\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`\r\n }\r\n\r\n\r\n/**\r\n * Checks if the current URL has a redirect loop\r\n * @param currentPath - The current pathname\r\n * @param redirectPath - The path we're trying to redirect to\r\n * @returns boolean indicating if there's a redirect loop\r\n */\r\nexport const hasRedirectLoop = (currentPath: string, redirectPath: string): boolean => {\r\n if (!currentPath || !redirectPath) return false\r\n\r\n // Remove any query parameters for comparison\r\n const cleanCurrentPath = currentPath.split(\"?\")[0]\r\n const cleanRedirectPath = redirectPath.split(\"?\")[0]\r\n\r\n return cleanCurrentPath === cleanRedirectPath\r\n}\r\n \r\n/**\r\n * Constructs a URL with redirect parameters while preventing loops\r\n * @param path - The base path (usually login path)\r\n * @param redirectUrl - The URL to redirect to after action completes\r\n * @param loginPath - The login path to check against\r\n * @param signUpPath - The sign up path to check against\r\n * @returns The full URL with redirect parameters\r\n */\r\nexport const constructUrlWithRedirect = (\r\n path: string,\r\n redirectUrl: string | undefined,\r\n): string => {\r\n const url = new URL(path, typeof window !== \"undefined\" ? window.location.origin : undefined)\r\n \r\n if (redirectUrl && !isAuthRoute(redirectUrl) && !isInternalRoute(redirectUrl)) {\r\n url.searchParams.set(\"redirect\", redirectUrl)\r\n }\r\n \r\n return url.toString()\r\n}\r\n\r\n/**\r\n * Stores the current path before signing out\r\n */\r\nexport const storePreviousPath = (path: string): void => {\r\n if (typeof window !== \"undefined\" && !isAuthRoute(path)) {\r\n sessionStorage.setItem(\"previousPath\", path)\r\n }\r\n}\r\n\r\n/**\r\n * Gets the stored previous path\r\n */\r\nexport const getPreviousPath = (): string | null => {\r\n if (typeof window !== \"undefined\") {\r\n return sessionStorage.getItem(\"previousPath\")\r\n }\r\n return null\r\n}\r\n\r\n\r\n \r\n/**\r\n * Gets a validated redirect URL ensuring it's from the same origin\r\n * @param redirectUrl - The URL to validate\r\n * @param searchParams - The search parameters to check for redirect\r\n * @returns A validated redirect URL\r\n */\r\nexport const getValidRedirectUrl = (\r\n searchParams: URLSearchParams,\r\n configuredRedirect?: string,\r\n): string => {\r\n // Check URL search param first (highest priority)\r\n const urlRedirect = searchParams.get(\"redirect\")\r\n if (urlRedirect) {\r\n return validateUrl(urlRedirect)\r\n }\r\n\r\n // Then check configured redirect (for first visits)\r\n if (configuredRedirect) {\r\n return validateUrl(configuredRedirect)\r\n }\r\n\r\n // Default fallback\r\n return \"/\"\r\n}\r\n\r\n/**\r\n * Validates and sanitizes URLs\r\n */\r\nconst validateUrl = (url: string): string => {\r\n try {\r\n // For absolute URLs\r\n if (url.startsWith(\"http\")) {\r\n const urlObj = new URL(url)\r\n if (typeof window !== \"undefined\" && urlObj.origin !== window.location.origin) {\r\n return \"/\"\r\n }\r\n return !isAuthRoute(urlObj.pathname) && !isInternalRoute(urlObj.pathname) \r\n ? urlObj.pathname \r\n : \"/\"\r\n }\r\n \r\n // For relative URLs\r\n return !isAuthRoute(url) && !isInternalRoute(url) ? url : \"/\"\r\n } catch {\r\n return \"/\"\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"],"mappings":"AAEA,SAAS,aAAY,uBAAuB;AAOrC,MAAM,mBAAmB,CAAC,SAAiB;AAChD,MAAI,OAAO,WAAW,YAAa,QAAO;AACxC,QAAM,UAAU,OAAO,SAAS;AAChC,MAAI,KAAK,WAAW,MAAM,GAAG;AAC3B,WAAO;AAAA,EACT;AACA,SAAO,GAAG,OAAO,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AAC9D;AASK,MAAM,kBAAkB,CAAC,aAAqB,iBAAkC;AACrF,MAAI,CAAC,eAAe,CAAC,aAAc,QAAO;AAG1C,QAAM,mBAAmB,YAAY,MAAM,GAAG,EAAE,CAAC;AACjD,QAAM,oBAAoB,aAAa,MAAM,GAAG,EAAE,CAAC;AAEnD,SAAO,qBAAqB;AAC9B;AAUO,MAAM,2BAA2B,CACtC,MACA,gBACW;AACX,QAAM,MAAM,IAAI,IAAI,MAAM,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS,MAAS;AAE5F,MAAI,eAAe,CAAC,YAAY,WAAW,KAAK,CAAC,gBAAgB,WAAW,GAAG;AAC7E,QAAI,aAAa,IAAI,YAAY,WAAW;AAAA,EAC9C;AAEA,SAAO,IAAI,SAAS;AACtB;AAKO,MAAM,oBAAoB,CAAC,SAAuB;AACvD,MAAI,OAAO,WAAW,eAAe,CAAC,YAAY,IAAI,GAAG;AACvD,mBAAe,QAAQ,gBAAgB,IAAI;AAAA,EAC7C;AACF;AAKO,MAAM,kBAAkB,MAAqB;AAClD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,eAAe,QAAQ,cAAc;AAAA,EAC9C;AACA,SAAO;AACT;AAUO,MAAM,sBAAsB,CACjC,cACA,uBACW;AAEX,QAAM,cAAc,aAAa,IAAI,UAAU;AAC/C,MAAI,aAAa;AACf,WAAO,YAAY,WAAW;AAAA,EAChC;AAGA,MAAI,oBAAoB;AACtB,WAAO,YAAY,kBAAkB;AAAA,EACvC;AAGA,SAAO;AACT;AAKA,MAAM,cAAc,CAAC,QAAwB;AAC3C,MAAI;AAEF,QAAI,IAAI,WAAW,MAAM,GAAG;AAC1B,YAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,UAAI,OAAO,WAAW,eAAe,OAAO,WAAW,OAAO,SAAS,QAAQ;AAC7E,eAAO;AAAA,MACT;AACA,aAAO,CAAC,YAAY,OAAO,QAAQ,KAAK,CAAC,gBAAgB,OAAO,QAAQ,IACpE,OAAO,WACP;AAAA,IACN;AAGA,WAAO,CAAC,YAAY,GAAG,KAAK,CAAC,gBAAgB,GAAG,IAAI,MAAM;AAAA,EAC5D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const config = {
|
|
2
|
+
apiKey: process.env.FIREBASE_SERVER_API_KEY
|
|
3
|
+
};
|
|
4
|
+
Object.keys(config).forEach((key) => {
|
|
5
|
+
const configValue = config[key] + "";
|
|
6
|
+
if (configValue.charAt(0) === '"') {
|
|
7
|
+
config[key] = configValue.substring(1, configValue.length - 1);
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
const firebaseConfig = config;
|
|
11
|
+
export {
|
|
12
|
+
firebaseConfig
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=fireconfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/fireconfig.js"],"sourcesContent":["const config = {\n apiKey: process.env.FIREBASE_SERVER_API_KEY,\n};\n\n// When deployed, there are quotes that need to be stripped\nObject.keys(config).forEach((key) => {\n const configValue = config[key] + \"\";\n if (configValue.charAt(0) === '\"') {\n config[key] = configValue.substring(1, configValue.length - 1);\n }\n});\n\nexport const firebaseConfig = config;"],"mappings":"AAAA,MAAM,SAAS;AAAA,EACb,QAAQ,QAAQ,IAAI;AACtB;AAGA,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,QAAQ;AACnC,QAAM,cAAc,OAAO,GAAG,IAAI;AAClC,MAAI,YAAY,OAAO,CAAC,MAAM,KAAK;AACjC,WAAO,GAAG,IAAI,YAAY,UAAU,GAAG,YAAY,SAAS,CAAC;AAAA,EAC/D;AACF,CAAC;AAEM,MAAM,iBAAiB;","names":[]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
2
|
+
LogLevel2[LogLevel2["ERROR"] = 0] = "ERROR";
|
|
3
|
+
LogLevel2[LogLevel2["WARN"] = 1] = "WARN";
|
|
4
|
+
LogLevel2[LogLevel2["INFO"] = 2] = "INFO";
|
|
5
|
+
LogLevel2[LogLevel2["DEBUG"] = 3] = "DEBUG";
|
|
6
|
+
return LogLevel2;
|
|
7
|
+
})(LogLevel || {});
|
|
8
|
+
class Logger {
|
|
9
|
+
options;
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.options = {
|
|
12
|
+
enabled: false,
|
|
13
|
+
level: 2 /* INFO */,
|
|
14
|
+
prefix: "[TernSecure]",
|
|
15
|
+
...options
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
enable() {
|
|
19
|
+
this.options.enabled = true;
|
|
20
|
+
}
|
|
21
|
+
disable() {
|
|
22
|
+
this.options.enabled = false;
|
|
23
|
+
}
|
|
24
|
+
setLevel(level) {
|
|
25
|
+
this.options.level = level;
|
|
26
|
+
}
|
|
27
|
+
setPrefix(prefix) {
|
|
28
|
+
this.options.prefix = prefix;
|
|
29
|
+
}
|
|
30
|
+
log(level, levelName, message, ...args) {
|
|
31
|
+
if (!this.options.enabled || level > this.options.level) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
35
|
+
const formattedMessage = `${timestamp} ${this.options.prefix} [${levelName}] ${message}`;
|
|
36
|
+
switch (level) {
|
|
37
|
+
case 0 /* ERROR */:
|
|
38
|
+
console.error(formattedMessage, ...args);
|
|
39
|
+
break;
|
|
40
|
+
case 1 /* WARN */:
|
|
41
|
+
console.warn(formattedMessage, ...args);
|
|
42
|
+
break;
|
|
43
|
+
case 2 /* INFO */:
|
|
44
|
+
console.info(formattedMessage, ...args);
|
|
45
|
+
break;
|
|
46
|
+
case 3 /* DEBUG */:
|
|
47
|
+
console.debug(formattedMessage, ...args);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
error(message, ...args) {
|
|
52
|
+
this.log(0 /* ERROR */, "ERROR", message, ...args);
|
|
53
|
+
}
|
|
54
|
+
warn(message, ...args) {
|
|
55
|
+
this.log(1 /* WARN */, "WARN", message, ...args);
|
|
56
|
+
}
|
|
57
|
+
info(message, ...args) {
|
|
58
|
+
this.log(2 /* INFO */, "INFO", message, ...args);
|
|
59
|
+
}
|
|
60
|
+
debug(message, ...args) {
|
|
61
|
+
this.log(3 /* DEBUG */, "DEBUG", message, ...args);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const createLogger = (options) => {
|
|
65
|
+
return new Logger(options);
|
|
66
|
+
};
|
|
67
|
+
const middlewareLogger = createLogger({ prefix: "[TernSecure-Middleware]" });
|
|
68
|
+
export {
|
|
69
|
+
LogLevel,
|
|
70
|
+
Logger,
|
|
71
|
+
createLogger,
|
|
72
|
+
middlewareLogger
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/logger.ts"],"sourcesContent":["export enum LogLevel {\n ERROR = 0,\n WARN = 1,\n INFO = 2,\n DEBUG = 3,\n}\n\nexport interface LoggerOptions {\n enabled: boolean\n level: LogLevel\n prefix: string\n}\n\nexport class Logger {\n private options: LoggerOptions\n\n constructor(options: Partial<LoggerOptions> = {}) {\n this.options = {\n enabled: false,\n level: LogLevel.INFO,\n prefix: '[TernSecure]',\n ...options,\n }\n }\n\n enable(): void {\n this.options.enabled = true\n }\n\n disable(): void {\n this.options.enabled = false\n }\n\n setLevel(level: LogLevel): void {\n this.options.level = level\n }\n\n setPrefix(prefix: string): void {\n this.options.prefix = prefix\n }\n\n private log(level: LogLevel, levelName: string, message: string, ...args: any[]): void {\n if (!this.options.enabled || level > this.options.level) {\n return\n }\n\n const timestamp = new Date().toISOString()\n const formattedMessage = `${timestamp} ${this.options.prefix} [${levelName}] ${message}`\n \n switch (level) {\n case LogLevel.ERROR:\n console.error(formattedMessage, ...args)\n break\n case LogLevel.WARN:\n console.warn(formattedMessage, ...args)\n break\n case LogLevel.INFO:\n console.info(formattedMessage, ...args)\n break\n case LogLevel.DEBUG:\n console.debug(formattedMessage, ...args)\n break\n }\n }\n\n error(message: string, ...args: any[]): void {\n this.log(LogLevel.ERROR, 'ERROR', message, ...args)\n }\n\n warn(message: string, ...args: any[]): void {\n this.log(LogLevel.WARN, 'WARN', message, ...args)\n }\n\n info(message: string, ...args: any[]): void {\n this.log(LogLevel.INFO, 'INFO', message, ...args)\n }\n\n debug(message: string, ...args: any[]): void {\n this.log(LogLevel.DEBUG, 'DEBUG', message, ...args)\n }\n}\n\nexport const createLogger = (options?: Partial<LoggerOptions>): Logger => {\n return new Logger(options)\n}\n\nexport const middlewareLogger = createLogger({ prefix: '[TernSecure-Middleware]' })"],"mappings":"AAAO,IAAK,WAAL,kBAAKA,cAAL;AACL,EAAAA,oBAAA,WAAQ,KAAR;AACA,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,UAAO,KAAP;AACA,EAAAA,oBAAA,WAAQ,KAAR;AAJU,SAAAA;AAAA,GAAA;AAaL,MAAM,OAAO;AAAA,EACV;AAAA,EAER,YAAY,UAAkC,CAAC,GAAG;AAChD,SAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EAEA,SAAe;AACb,SAAK,QAAQ,UAAU;AAAA,EACzB;AAAA,EAEA,UAAgB;AACd,SAAK,QAAQ,UAAU;AAAA,EACzB;AAAA,EAEA,SAAS,OAAuB;AAC9B,SAAK,QAAQ,QAAQ;AAAA,EACvB;AAAA,EAEA,UAAU,QAAsB;AAC9B,SAAK,QAAQ,SAAS;AAAA,EACxB;AAAA,EAEQ,IAAI,OAAiB,WAAmB,YAAoB,MAAmB;AACrF,QAAI,CAAC,KAAK,QAAQ,WAAW,QAAQ,KAAK,QAAQ,OAAO;AACvD;AAAA,IACF;AAEA,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,mBAAmB,GAAG,SAAS,IAAI,KAAK,QAAQ,MAAM,KAAK,SAAS,KAAK,OAAO;AAEtF,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,gBAAQ,MAAM,kBAAkB,GAAG,IAAI;AACvC;AAAA,MACF,KAAK;AACH,gBAAQ,KAAK,kBAAkB,GAAG,IAAI;AACtC;AAAA,MACF,KAAK;AACH,gBAAQ,KAAK,kBAAkB,GAAG,IAAI;AACtC;AAAA,MACF,KAAK;AACH,gBAAQ,MAAM,kBAAkB,GAAG,IAAI;AACvC;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAM,YAAoB,MAAmB;AAC3C,SAAK,IAAI,eAAgB,SAAS,SAAS,GAAG,IAAI;AAAA,EACpD;AAAA,EAEA,KAAK,YAAoB,MAAmB;AAC1C,SAAK,IAAI,cAAe,QAAQ,SAAS,GAAG,IAAI;AAAA,EAClD;AAAA,EAEA,KAAK,YAAoB,MAAmB;AAC1C,SAAK,IAAI,cAAe,QAAQ,SAAS,GAAG,IAAI;AAAA,EAClD;AAAA,EAEA,MAAM,YAAoB,MAAmB;AAC3C,SAAK,IAAI,eAAgB,SAAS,SAAS,GAAG,IAAI;AAAA,EACpD;AACF;AAEO,MAAM,eAAe,CAAC,YAA6C;AACxE,SAAO,IAAI,OAAO,OAAO;AAC3B;AAEO,MAAM,mBAAmB,aAAa,EAAE,QAAQ,0BAA0B,CAAC;","names":["LogLevel"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/redis.ts"],"sourcesContent":["import { Redis } from \"@upstash/redis\"\n\nexport const redis = new Redis({\n url: process.env.KV_REST_API_URL,\n token: process.env.KV_REST_API_TOKEN,\n})\n\nexport interface DisabledUserRecord {\n uid: string\n email: string\n disabledTime: string\n}\n"],"mappings":"AAAA,SAAS,aAAa;AAEf,MAAM,QAAQ,IAAI,MAAM;AAAA,EAC7B,KAAK,QAAQ,IAAI;AAAA,EACjB,OAAO,QAAQ,IAAI;AACrB,CAAC;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { constants as nextConstants } from "../constants";
|
|
2
|
+
const isRedirect = (res) => {
|
|
3
|
+
return res.headers.get(nextConstants.Headers.NextRedirect);
|
|
4
|
+
};
|
|
5
|
+
const setHeader = (res, name, val) => {
|
|
6
|
+
res.headers.set(name, val);
|
|
7
|
+
return res;
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
isRedirect,
|
|
11
|
+
setHeader
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/response.ts"],"sourcesContent":["import { constants as nextConstants } from '../constants';\n\nexport const isRedirect = (res: Response) => {\n return res.headers.get(nextConstants.Headers.NextRedirect);\n};\n\nexport const setHeader = <T extends Response>(res: T, name: string, val: string): T => {\n res.headers.set(name, val);\n return res;\n};\n"],"mappings":"AAAA,SAAS,aAAa,qBAAqB;AAEpC,MAAM,aAAa,CAAC,QAAkB;AAC3C,SAAO,IAAI,QAAQ,IAAI,cAAc,QAAQ,YAAY;AAC3D;AAEO,MAAM,YAAY,CAAqB,KAAQ,MAAc,QAAmB;AACrF,MAAI,QAAQ,IAAI,MAAM,GAAG;AACzB,SAAO;AACT;","names":[]}
|