@tern-secure/nextjs 5.2.0-canary.v20251030165007 → 5.2.0-canary.v20251125170702
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/app-router/admin/actions.js +5 -0
- package/dist/cjs/app-router/admin/actions.js.map +1 -1
- package/dist/cjs/app-router/admin/cookieOptionsHelper.js +28 -16
- package/dist/cjs/app-router/admin/cookieOptionsHelper.js.map +1 -1
- package/dist/cjs/app-router/admin/endpointRouter.js +10 -1
- package/dist/cjs/app-router/admin/endpointRouter.js.map +1 -1
- package/dist/cjs/app-router/admin/request.js +6 -1
- package/dist/cjs/app-router/admin/request.js.map +1 -1
- package/dist/cjs/app-router/admin/sessionHandlers.js +79 -7
- package/dist/cjs/app-router/admin/sessionHandlers.js.map +1 -1
- package/dist/cjs/app-router/admin/signInCreateHandler.js +213 -0
- package/dist/cjs/app-router/admin/signInCreateHandler.js.map +1 -0
- package/dist/cjs/app-router/admin/types.js +33 -11
- package/dist/cjs/app-router/admin/types.js.map +1 -1
- package/dist/cjs/app-router/client/TernSecureProvider.js +5 -1
- package/dist/cjs/app-router/client/TernSecureProvider.js.map +1 -1
- package/dist/cjs/app-router/server/TernSecureProvider.js +1 -1
- package/dist/cjs/app-router/server/TernSecureProvider.js.map +1 -1
- package/dist/cjs/app-router/server/auth.js +1 -1
- package/dist/cjs/app-router/server/auth.js.map +1 -1
- package/dist/cjs/boundary/components.js +2 -12
- package/dist/cjs/boundary/components.js.map +1 -1
- package/dist/cjs/{app-router/server/auth_new.js → components/uiComponents.js} +18 -17
- package/dist/cjs/components/uiComponents.js.map +1 -0
- package/dist/cjs/index.js +9 -15
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/server/data/getAuthDataFromRequest.js +15 -15
- package/dist/cjs/server/data/getAuthDataFromRequest.js.map +1 -1
- package/dist/cjs/server/index.js +3 -6
- package/dist/cjs/server/index.js.map +1 -1
- package/dist/cjs/server/{ternSecureEdgeMiddleware.js → ternSecureProxy.js} +32 -9
- package/dist/cjs/server/ternSecureProxy.js.map +1 -0
- package/dist/cjs/server/utils.js +1 -1
- package/dist/cjs/server/utils.js.map +1 -1
- package/dist/cjs/utils/allNextProviderProps.js +17 -3
- package/dist/cjs/utils/allNextProviderProps.js.map +1 -1
- package/dist/cjs/utils/config.js +1 -0
- package/dist/cjs/utils/config.js.map +1 -1
- package/dist/cjs/utils/tern-ui-script.js +72 -0
- package/dist/cjs/utils/tern-ui-script.js.map +1 -0
- package/dist/esm/app-router/admin/actions.js +5 -0
- package/dist/esm/app-router/admin/actions.js.map +1 -1
- package/dist/esm/app-router/admin/cookieOptionsHelper.js +26 -15
- package/dist/esm/app-router/admin/cookieOptionsHelper.js.map +1 -1
- package/dist/esm/app-router/admin/endpointRouter.js +11 -2
- package/dist/esm/app-router/admin/endpointRouter.js.map +1 -1
- package/dist/esm/app-router/admin/request.js +7 -2
- package/dist/esm/app-router/admin/request.js.map +1 -1
- package/dist/esm/app-router/admin/sessionHandlers.js +83 -7
- package/dist/esm/app-router/admin/sessionHandlers.js.map +1 -1
- package/dist/esm/app-router/admin/signInCreateHandler.js +188 -0
- package/dist/esm/app-router/admin/signInCreateHandler.js.map +1 -0
- package/dist/esm/app-router/admin/types.js +30 -10
- package/dist/esm/app-router/admin/types.js.map +1 -1
- package/dist/esm/app-router/client/TernSecureProvider.js +6 -2
- package/dist/esm/app-router/client/TernSecureProvider.js.map +1 -1
- package/dist/esm/app-router/server/TernSecureProvider.js +2 -2
- package/dist/esm/app-router/server/TernSecureProvider.js.map +1 -1
- package/dist/esm/app-router/server/auth.js +2 -2
- package/dist/esm/app-router/server/auth.js.map +1 -1
- package/dist/esm/boundary/components.js +1 -11
- package/dist/esm/boundary/components.js.map +1 -1
- package/dist/esm/components/uiComponents.js +21 -0
- package/dist/esm/components/uiComponents.js.map +1 -0
- package/dist/esm/index.js +10 -14
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/data/getAuthDataFromRequest.js +21 -13
- package/dist/esm/server/data/getAuthDataFromRequest.js.map +1 -1
- package/dist/esm/server/index.js +2 -8
- package/dist/esm/server/index.js.map +1 -1
- package/dist/esm/server/{ternSecureEdgeMiddleware.js → ternSecureProxy.js} +30 -7
- package/dist/esm/server/ternSecureProxy.js.map +1 -0
- package/dist/esm/server/utils.js +1 -1
- package/dist/esm/server/utils.js.map +1 -1
- package/dist/esm/utils/allNextProviderProps.js +17 -3
- package/dist/esm/utils/allNextProviderProps.js.map +1 -1
- package/dist/esm/utils/config.js +1 -0
- package/dist/esm/utils/config.js.map +1 -1
- package/dist/esm/utils/tern-ui-script.js +38 -0
- package/dist/esm/utils/tern-ui-script.js.map +1 -0
- package/dist/types/app-router/admin/actions.d.ts +23 -0
- package/dist/types/app-router/admin/actions.d.ts.map +1 -1
- package/dist/types/app-router/admin/cookieOptionsHelper.d.ts +2 -10
- package/dist/types/app-router/admin/cookieOptionsHelper.d.ts.map +1 -1
- package/dist/types/app-router/admin/endpointRouter.d.ts.map +1 -1
- package/dist/types/app-router/admin/request.d.ts.map +1 -1
- package/dist/types/app-router/admin/sessionHandlers.d.ts +4 -3
- package/dist/types/app-router/admin/sessionHandlers.d.ts.map +1 -1
- package/dist/types/app-router/admin/signInCreateHandler.d.ts +11 -0
- package/dist/types/app-router/admin/signInCreateHandler.d.ts.map +1 -0
- package/dist/types/app-router/admin/types.d.ts +5 -3
- package/dist/types/app-router/admin/types.d.ts.map +1 -1
- package/dist/types/app-router/client/TernSecureProvider.d.ts.map +1 -1
- package/dist/types/app-router/server/auth.d.ts.map +1 -1
- package/dist/types/boundary/components.d.ts +1 -1
- package/dist/types/boundary/components.d.ts.map +1 -1
- package/dist/types/components/uiComponents.d.ts +6 -0
- package/dist/types/components/uiComponents.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/server/data/getAuthDataFromRequest.d.ts +6 -6
- package/dist/types/server/data/getAuthDataFromRequest.d.ts.map +1 -1
- package/dist/types/server/index.d.ts +1 -2
- package/dist/types/server/index.d.ts.map +1 -1
- package/dist/types/server/{ternSecureEdgeMiddleware.d.ts → ternSecureProxy.d.ts} +2 -2
- package/dist/types/server/ternSecureProxy.d.ts.map +1 -0
- package/dist/types/utils/allNextProviderProps.d.ts.map +1 -1
- package/dist/types/utils/config.d.ts.map +1 -1
- package/dist/types/utils/tern-ui-script.d.ts +8 -0
- package/dist/types/utils/tern-ui-script.d.ts.map +1 -0
- package/package.json +7 -9
- package/dist/cjs/app-router/server/TernSecureProviderNode.js +0 -92
- package/dist/cjs/app-router/server/TernSecureProviderNode.js.map +0 -1
- package/dist/cjs/app-router/server/auth_new.js.map +0 -1
- package/dist/cjs/server/ternSecureEdgeMiddleware.js.map +0 -1
- package/dist/cjs/utils/admin-init.js +0 -4
- package/dist/cjs/utils/admin-init.js.map +0 -1
- package/dist/cjs/utils/client-init.js +0 -4
- package/dist/cjs/utils/client-init.js.map +0 -1
- package/dist/esm/app-router/server/TernSecureProviderNode.js +0 -58
- package/dist/esm/app-router/server/TernSecureProviderNode.js.map +0 -1
- package/dist/esm/app-router/server/auth_new.js +0 -17
- package/dist/esm/app-router/server/auth_new.js.map +0 -1
- package/dist/esm/server/ternSecureEdgeMiddleware.js.map +0 -1
- package/dist/esm/utils/admin-init.js +0 -3
- package/dist/esm/utils/admin-init.js.map +0 -1
- package/dist/esm/utils/client-init.js +0 -3
- package/dist/esm/utils/client-init.js.map +0 -1
- package/dist/types/app-router/server/TernSecureProviderNode.d.ts +0 -4
- package/dist/types/app-router/server/TernSecureProviderNode.d.ts.map +0 -1
- package/dist/types/app-router/server/auth_new.d.ts +0 -14
- package/dist/types/app-router/server/auth_new.d.ts.map +0 -1
- package/dist/types/server/ternSecureEdgeMiddleware.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/client-init.d.ts +0 -2
- package/dist/types/utils/client-init.d.ts.map +0 -1
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
FIREBASE_PROJECT_ID,
|
|
11
11
|
FIREBASE_STORAGE_BUCKET
|
|
12
12
|
} from "./constants";
|
|
13
|
-
import {
|
|
13
|
+
import { getIdTokenCookieOptions } from "./cookieOptionsHelper";
|
|
14
14
|
async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer) {
|
|
15
15
|
const backendClient = await ternSecureBackendClient();
|
|
16
16
|
const authOptions = {
|
|
@@ -25,7 +25,7 @@ async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer)
|
|
|
25
25
|
},
|
|
26
26
|
apiClient: backendClient
|
|
27
27
|
};
|
|
28
|
-
const COOKIE_OPTIONS =
|
|
28
|
+
const COOKIE_OPTIONS = getIdTokenCookieOptions();
|
|
29
29
|
const { createCustomIdAndRefreshToken } = getAuth(authOptions);
|
|
30
30
|
const customTokens = await createCustomIdAndRefreshToken(idToken, { referer: referrer });
|
|
31
31
|
const cookiePrefix = getCookiePrefix();
|
|
@@ -39,6 +39,11 @@ async function refreshCookieWithIdToken(idToken, cookieStore, config, referrer)
|
|
|
39
39
|
getCookieName(constants.Cookies.Refresh, cookiePrefix),
|
|
40
40
|
customTokens.refreshToken,
|
|
41
41
|
COOKIE_OPTIONS
|
|
42
|
+
),
|
|
43
|
+
cookieStore.set(
|
|
44
|
+
constants.Cookies.TernAut,
|
|
45
|
+
customTokens.auth_time.toString(),
|
|
46
|
+
{ secure: true, maxAge: 365 * 24 * 60 * 60 }
|
|
42
47
|
)
|
|
43
48
|
];
|
|
44
49
|
if (config?.enableCustomToken) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/request.ts"],"sourcesContent":["import type { AuthenticateRequestOptions } from '@tern-secure/backend';\nimport { constants } from '@tern-secure/backend';\nimport { getAuth } from '@tern-secure/backend/auth';\nimport { getCookieName, getCookiePrefix } from '@tern-secure/shared/cookie';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport type { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport {\n FIREBASE_API_KEY,\n FIREBASE_APP_ID,\n FIREBASE_AUTH_DOMAIN,\n FIREBASE_MESSAGING_SENDER_ID,\n FIREBASE_PROJECT_ID,\n FIREBASE_STORAGE_BUCKET,\n} from './constants';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/request.ts"],"sourcesContent":["import type { AuthenticateRequestOptions } from '@tern-secure/backend';\nimport { constants } from '@tern-secure/backend';\nimport { getAuth } from '@tern-secure/backend/auth';\nimport { getCookieName, getCookiePrefix } from '@tern-secure/shared/cookie';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport type { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport {\n FIREBASE_API_KEY,\n FIREBASE_APP_ID,\n FIREBASE_AUTH_DOMAIN,\n FIREBASE_MESSAGING_SENDER_ID,\n FIREBASE_PROJECT_ID,\n FIREBASE_STORAGE_BUCKET,\n} from './constants';\nimport { getIdTokenCookieOptions } from './cookieOptionsHelper';\nimport type { TernSecureHandlerOptions } from './types';\n\nexport async function refreshCookieWithIdToken(\n idToken: string,\n cookieStore: NextCookieStore,\n config?: TernSecureHandlerOptions,\n referrer?: string,\n): Promise<void> {\n const backendClient = await ternSecureBackendClient();\n\n const authOptions: AuthenticateRequestOptions = {\n tenantId: config?.tenantId || undefined,\n firebaseConfig: {\n apiKey: FIREBASE_API_KEY,\n authDomain: FIREBASE_AUTH_DOMAIN,\n projectId: FIREBASE_PROJECT_ID,\n storageBucket: FIREBASE_STORAGE_BUCKET,\n messagingSenderId: FIREBASE_MESSAGING_SENDER_ID,\n appId: FIREBASE_APP_ID,\n },\n apiClient: backendClient,\n };\n\n const COOKIE_OPTIONS = getIdTokenCookieOptions();\n\n const { createCustomIdAndRefreshToken } = getAuth(authOptions);\n\n const customTokens = await createCustomIdAndRefreshToken(idToken, { referer: referrer });\n\n const cookiePrefix = getCookiePrefix();\n\n const cookiePromises = [\n cookieStore.set(\n getCookieName(constants.Cookies.IdToken, cookiePrefix),\n customTokens.idToken,\n COOKIE_OPTIONS,\n ),\n cookieStore.set(\n getCookieName(constants.Cookies.Refresh, cookiePrefix),\n customTokens.refreshToken,\n COOKIE_OPTIONS,\n ),\n\n cookieStore.set(\n constants.Cookies.TernAut,\n customTokens.auth_time.toString(),\n { secure: true, maxAge: 365 * 24 * 60 * 60 }\n ),\n ];\n\n if (config?.enableCustomToken) {\n cookiePromises.push(\n cookieStore.set(constants.Cookies.Custom, customTokens.customToken, COOKIE_OPTIONS),\n );\n }\n\n await Promise.all(cookiePromises);\n}\n"],"mappings":"AACA,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AACxB,SAAS,eAAe,uBAAuB;AAE/C,SAAS,+BAA+B;AAExC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,+BAA+B;AAGxC,eAAsB,yBACpB,SACA,aACA,QACA,UACe;AACf,QAAM,gBAAgB,MAAM,wBAAwB;AAEpD,QAAM,cAA0C;AAAA,IAC9C,UAAU,QAAQ,YAAY;AAAA,IAC9B,gBAAgB;AAAA,MACd,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,eAAe;AAAA,MACf,mBAAmB;AAAA,MACnB,OAAO;AAAA,IACT;AAAA,IACA,WAAW;AAAA,EACb;AAEA,QAAM,iBAAiB,wBAAwB;AAE/C,QAAM,EAAE,8BAA8B,IAAI,QAAQ,WAAW;AAE7D,QAAM,eAAe,MAAM,8BAA8B,SAAS,EAAE,SAAS,SAAS,CAAC;AAEvF,QAAM,eAAe,gBAAgB;AAErC,QAAM,iBAAiB;AAAA,IACrB,YAAY;AAAA,MACV,cAAc,UAAU,QAAQ,SAAS,YAAY;AAAA,MACrD,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV,cAAc,UAAU,QAAQ,SAAS,YAAY;AAAA,MACrD,aAAa;AAAA,MACb;AAAA,IACF;AAAA,IAEA,YAAY;AAAA,MACV,UAAU,QAAQ;AAAA,MAClB,aAAa,UAAU,SAAS;AAAA,MAChC,EAAE,QAAQ,MAAM,QAAQ,MAAM,KAAK,KAAK,GAAG;AAAA,IAC7C;AAAA,EACF;AAEA,MAAI,QAAQ,mBAAmB;AAC7B,mBAAe;AAAA,MACb,YAAY,IAAI,UAAU,QAAQ,QAAQ,aAAa,aAAa,cAAc;AAAA,IACpF;AAAA,EACF;AAEA,QAAM,QAAQ,IAAI,cAAc;AAClC;","names":[]}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
import { constants } from "@tern-secure/backend";
|
|
1
2
|
import { clearSessionCookie } from "@tern-secure/backend/admin";
|
|
2
3
|
import { ternDecodeJwtUnguarded } from "@tern-secure/backend/jwt";
|
|
4
|
+
import { ternSecureBackendClient } from "../../server/ternsecureClient";
|
|
3
5
|
import { NextCookieStore } from "../../utils/NextCookieAdapter";
|
|
6
|
+
import { FIREBASE_API_KEY } from "./constants";
|
|
4
7
|
import { createValidators } from "./fnValidators";
|
|
5
8
|
import { refreshCookieWithIdToken } from "./request";
|
|
6
|
-
import {
|
|
7
|
-
|
|
9
|
+
import {
|
|
10
|
+
createApiErrorResponse,
|
|
11
|
+
createApiSuccessResponse,
|
|
12
|
+
HttpResponseHelper,
|
|
13
|
+
SessionResponseHelper
|
|
14
|
+
} from "./responses";
|
|
15
|
+
import { processSignInCreate } from "./signInCreateHandler";
|
|
16
|
+
const sessionEndpointHandler = async (context, config) => {
|
|
8
17
|
const { subEndpoint, method, referrer } = context;
|
|
9
18
|
const validators = createValidators(context);
|
|
10
19
|
const {
|
|
@@ -50,7 +59,7 @@ async function sessionEndpointHandler(context, config) {
|
|
|
50
59
|
const cookieStore = new NextCookieStore();
|
|
51
60
|
const { idToken, csrfToken, error } = await validateSessionRequest();
|
|
52
61
|
if (error) return error;
|
|
53
|
-
const csrfCookieValue = await cookieStore.get(
|
|
62
|
+
const csrfCookieValue = await cookieStore.get(constants.Cookies.CsrfToken);
|
|
54
63
|
validateCsrfToken(csrfToken || "", csrfCookieValue.value);
|
|
55
64
|
const handleCreateSession = async (cookieStore2, idToken2) => {
|
|
56
65
|
try {
|
|
@@ -100,8 +109,8 @@ async function sessionEndpointHandler(context, config) {
|
|
|
100
109
|
default:
|
|
101
110
|
return HttpResponseHelper.createMethodNotAllowedResponse();
|
|
102
111
|
}
|
|
103
|
-
}
|
|
104
|
-
async
|
|
112
|
+
};
|
|
113
|
+
const cookieEndpointHandler = async (context, config) => {
|
|
105
114
|
const { subEndpoint, method } = context;
|
|
106
115
|
const validators = createValidators(context);
|
|
107
116
|
const { validateSecurity } = validators;
|
|
@@ -168,9 +177,76 @@ async function cookieEndpointHandler(context, config) {
|
|
|
168
177
|
default:
|
|
169
178
|
return HttpResponseHelper.createMethodNotAllowedResponse();
|
|
170
179
|
}
|
|
171
|
-
}
|
|
180
|
+
};
|
|
181
|
+
const signInEndpointHandler = async (context, config) => {
|
|
182
|
+
const { subEndpoint, method } = context;
|
|
183
|
+
const validators = createValidators(context);
|
|
184
|
+
const {
|
|
185
|
+
validateSubEndpoint,
|
|
186
|
+
validateSecurity
|
|
187
|
+
} = validators;
|
|
188
|
+
if (!subEndpoint) {
|
|
189
|
+
return createApiErrorResponse("SUB_ENDPOINT_REQUIRED", "Sign_ins sub-endpoint required", 400);
|
|
190
|
+
}
|
|
191
|
+
const signInsConfig = config.endpoints?.signIns;
|
|
192
|
+
const subEndpointConfig = signInsConfig?.subEndpoints?.[subEndpoint];
|
|
193
|
+
validateSubEndpoint(subEndpoint, subEndpointConfig);
|
|
194
|
+
if (subEndpointConfig?.security) {
|
|
195
|
+
await validateSecurity(subEndpointConfig.security);
|
|
196
|
+
}
|
|
197
|
+
const PostHandler = async (subEndpoint2) => {
|
|
198
|
+
const create = async () => {
|
|
199
|
+
return await processSignInCreate(context);
|
|
200
|
+
};
|
|
201
|
+
const passwordResetEmail = async () => {
|
|
202
|
+
try {
|
|
203
|
+
const body = await context.request.json();
|
|
204
|
+
const { email } = body;
|
|
205
|
+
if (!email || typeof email !== "string") {
|
|
206
|
+
return createApiErrorResponse("EMAIL_REQUIRED", "Email is required", 400);
|
|
207
|
+
}
|
|
208
|
+
const backendClient = await ternSecureBackendClient();
|
|
209
|
+
const response = await backendClient.signIn.resetPasswordEmail(FIREBASE_API_KEY, {
|
|
210
|
+
email,
|
|
211
|
+
requestType: "PASSWORD_RESET"
|
|
212
|
+
});
|
|
213
|
+
if (!response) {
|
|
214
|
+
return createApiErrorResponse(
|
|
215
|
+
"PASSWORD_RESET_FAILED",
|
|
216
|
+
"Failed to send password reset email",
|
|
217
|
+
500
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
return createApiSuccessResponse({
|
|
221
|
+
email
|
|
222
|
+
});
|
|
223
|
+
} catch (error) {
|
|
224
|
+
return createApiErrorResponse(
|
|
225
|
+
"PASSWORD_RESET_ERROR",
|
|
226
|
+
error instanceof Error ? error.message : "An error occurred while sending password reset email",
|
|
227
|
+
500
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
switch (subEndpoint2) {
|
|
232
|
+
case "create":
|
|
233
|
+
return create();
|
|
234
|
+
case "resetPasswordEmail":
|
|
235
|
+
return passwordResetEmail();
|
|
236
|
+
default:
|
|
237
|
+
return HttpResponseHelper.createSubEndpointNotSupportedResponse();
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
switch (method) {
|
|
241
|
+
case "POST":
|
|
242
|
+
return PostHandler(subEndpoint);
|
|
243
|
+
default:
|
|
244
|
+
return HttpResponseHelper.createMethodNotAllowedResponse();
|
|
245
|
+
}
|
|
246
|
+
};
|
|
172
247
|
export {
|
|
173
248
|
cookieEndpointHandler,
|
|
174
|
-
sessionEndpointHandler
|
|
249
|
+
sessionEndpointHandler,
|
|
250
|
+
signInEndpointHandler
|
|
175
251
|
};
|
|
176
252
|
//# sourceMappingURL=sessionHandlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\nimport type { CookieSubEndpoint } from '@tern-secure/types';\n\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { type RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { createValidators } from './fnValidators';\nimport { refreshCookieWithIdToken } from './request';\nimport { createApiErrorResponse, createApiSuccessResponse, HttpResponseHelper, SessionResponseHelper } from './responses';\nimport type { SessionSubEndpoint, TernSecureHandlerOptions } from './types';\n\nasync function sessionEndpointHandler(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n): Promise<Response> {\n const { subEndpoint, method, referrer } = context;\n\n const validators = createValidators(context);\n\n const {\n validateSubEndpoint,\n validateSecurity,\n validateSessionRequest,\n validateCsrfToken,\n validateIdToken,\n } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n const sessionsConfig = config.endpoints?.sessions;\n const subEndpointConfig = sessionsConfig?.subEndpoints?.[subEndpoint];\n\n validateSubEndpoint(subEndpoint, subEndpointConfig);\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\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 validateSessionRequest();\n if (error) return error;\n\n const csrfCookieValue = await cookieStore.get('_session_terncf');\n validateCsrfToken(csrfToken || '', csrfCookieValue.value);\n\n const handleCreateSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n await refreshCookieWithIdToken(idToken, cookieStore, config, referrer);\n return SessionResponseHelper.createSessionCreationResponse({\n success: true,\n message: 'Session created successfully',\n });\n } catch (error) {\n return createApiErrorResponse('SESSION_CREATION_FAILED', 'Session creation failed', 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(idToken, cookieStore, config);\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n return createApiErrorResponse('REFRESH_FAILED', 'Session refresh failed', 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 validateIdToken(idToken);\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);\n\n case 'POST':\n return SessionPostHandler(subEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\nasync function cookieEndpointHandler(\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n): Promise<Response> {\n const { subEndpoint, method } = context;\n\n const validators = createValidators(context);\n const { validateSecurity } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Cookie sub-endpoint required', 400);\n }\n\n const cookiesConfig = config.endpoints?.cookies;\n const subEndpointConfig = cookiesConfig?.subEndpoints?.[subEndpoint as CookieSubEndpoint];\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Cookie endpoint not found or disabled', 404);\n }\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\n\n const CookieGetHandler = async (subEndpoint: CookieSubEndpoint): Promise<Response> => {\n const handleGetCookie = async (): Promise<Response> => {\n try {\n const url = new URL(context.ternUrl);\n const tokenName = url.searchParams.get('tokenName');\n\n if (!tokenName) {\n return createApiErrorResponse('TOKEN_NAME_REQUIRED', 'tokenName query parameter is required', 400);\n }\n\n let cookieValue: string | undefined;\n\n switch (tokenName) {\n case 'idToken':\n cookieValue = context.idTokenInCookie;\n break;\n case 'sessionToken':\n cookieValue = context.sessionTokenInCookie;\n break;\n case 'refreshToken':\n cookieValue = context.refreshTokenInCookie;\n break;\n case 'customToken':\n cookieValue = context.customTokenInCookie;\n break;\n default:\n return createApiErrorResponse('INVALID_TOKEN_NAME', 'Invalid token name. Must be one of: idToken, sessionToken, refreshToken, customToken', 400);\n }\n\n if (!cookieValue) {\n return createApiErrorResponse(\n 'TOKEN_NOT_FOUND',\n `${tokenName} not found in httpOnly cookies`,\n 404\n );\n }\n\n return createApiSuccessResponse({\n token: cookieValue,\n });\n } catch (error) {\n return createApiErrorResponse('COOKIE_RETRIEVAL_FAILED', 'Failed to retrieve cookie', 500);\n }\n };\n\n switch (subEndpoint) {\n case 'get':\n return handleGetCookie();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return CookieGetHandler(subEndpoint as CookieSubEndpoint);\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\nexport { sessionEndpointHandler, cookieEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import { constants } from '@tern-secure/backend';\nimport { clearSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\nimport type { CookieSubEndpoint } from '@tern-secure/types';\n\nimport { ternSecureBackendClient } from '../../server/ternsecureClient';\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { type RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport { FIREBASE_API_KEY } from './constants';\nimport { createValidators } from './fnValidators';\nimport { refreshCookieWithIdToken } from './request';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n HttpResponseHelper,\n SessionResponseHelper,\n} from './responses';\nimport { processSignInCreate } from './signInCreateHandler';\nimport type { SessionSubEndpoint, SignInSubEndpoint, TernSecureHandlerOptions } from './types';\n\nconst sessionEndpointHandler = async (\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n): Promise<Response> => {\n const { subEndpoint, method, referrer } = context;\n\n const validators = createValidators(context);\n\n const {\n validateSubEndpoint,\n validateSecurity,\n validateSessionRequest,\n validateCsrfToken,\n validateIdToken,\n } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n const sessionsConfig = config.endpoints?.sessions;\n const subEndpointConfig = sessionsConfig?.subEndpoints?.[subEndpoint];\n\n validateSubEndpoint(subEndpoint, subEndpointConfig);\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\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 validateSessionRequest();\n if (error) return error;\n\n const csrfCookieValue = await cookieStore.get(constants.Cookies.CsrfToken);\n validateCsrfToken(csrfToken || '', csrfCookieValue.value);\n\n const handleCreateSession = async (\n cookieStore: NextCookieStore,\n idToken: string,\n ): Promise<Response> => {\n try {\n await refreshCookieWithIdToken(idToken, cookieStore, config, referrer);\n return SessionResponseHelper.createSessionCreationResponse({\n success: true,\n message: 'Session created successfully',\n });\n } catch (error) {\n return createApiErrorResponse('SESSION_CREATION_FAILED', 'Session creation failed', 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(idToken, cookieStore, config);\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n return createApiErrorResponse('REFRESH_FAILED', 'Session refresh failed', 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 validateIdToken(idToken);\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);\n\n case 'POST':\n return SessionPostHandler(subEndpoint);\n\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\nconst cookieEndpointHandler = async (\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions,\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n const validators = createValidators(context);\n const { validateSecurity } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Cookie sub-endpoint required', 400);\n }\n\n const cookiesConfig = config.endpoints?.cookies;\n const subEndpointConfig = cookiesConfig?.subEndpoints?.[subEndpoint as CookieSubEndpoint];\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Cookie endpoint not found or disabled', 404);\n }\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\n\n const CookieGetHandler = async (subEndpoint: CookieSubEndpoint): Promise<Response> => {\n const handleGetCookie = async (): Promise<Response> => {\n try {\n const url = new URL(context.ternUrl);\n const tokenName = url.searchParams.get('tokenName');\n\n if (!tokenName) {\n return createApiErrorResponse('TOKEN_NAME_REQUIRED', 'tokenName query parameter is required', 400);\n }\n\n let cookieValue: string | undefined;\n\n switch (tokenName) {\n case 'idToken':\n cookieValue = context.idTokenInCookie;\n break;\n case 'sessionToken':\n cookieValue = context.sessionTokenInCookie;\n break;\n case 'refreshToken':\n cookieValue = context.refreshTokenInCookie;\n break;\n case 'customToken':\n cookieValue = context.customTokenInCookie;\n break;\n default:\n return createApiErrorResponse('INVALID_TOKEN_NAME', 'Invalid token name. Must be one of: idToken, sessionToken, refreshToken, customToken', 400);\n }\n\n if (!cookieValue) {\n return createApiErrorResponse(\n 'TOKEN_NOT_FOUND',\n `${tokenName} not found in httpOnly cookies`,\n 404\n );\n }\n\n return createApiSuccessResponse({\n token: cookieValue,\n });\n } catch (error) {\n return createApiErrorResponse('COOKIE_RETRIEVAL_FAILED', 'Failed to retrieve cookie', 500);\n }\n };\n\n switch (subEndpoint) {\n case 'get':\n return handleGetCookie();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n };\n\n switch (method) {\n case 'GET':\n return CookieGetHandler(subEndpoint as CookieSubEndpoint);\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n}\n\nconst signInEndpointHandler = async (\n context: RequestProcessorContext,\n config: TernSecureHandlerOptions\n): Promise<Response> => {\n const { subEndpoint, method } = context;\n\n const validators = createValidators(context);\n\n const {\n validateSubEndpoint,\n validateSecurity,\n } = validators;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Sign_ins sub-endpoint required', 400);\n }\n\n const signInsConfig = config.endpoints?.signIns;\n const subEndpointConfig = signInsConfig?.subEndpoints?.[subEndpoint as SignInSubEndpoint];\n\n validateSubEndpoint(subEndpoint, subEndpointConfig);\n\n if (subEndpointConfig?.security) {\n await validateSecurity(subEndpointConfig.security);\n }\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 if (!email || typeof email !== 'string') {\n return createApiErrorResponse('EMAIL_REQUIRED', 'Email is required', 400);\n }\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 { cookieEndpointHandler, sessionEndpointHandler, signInEndpointHandler };\n"],"mappings":"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","names":["subEndpoint","cookieStore","idToken","error"]}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { RetrieveUser } from "./actions";
|
|
2
|
+
import {
|
|
3
|
+
createApiErrorResponse,
|
|
4
|
+
createApiSuccessResponse
|
|
5
|
+
} from "./responses";
|
|
6
|
+
const processSignInCreate = async (context) => {
|
|
7
|
+
try {
|
|
8
|
+
const body = await context.request.json();
|
|
9
|
+
const { strategy, identifier } = body;
|
|
10
|
+
if (!strategy) {
|
|
11
|
+
return createApiErrorResponse(
|
|
12
|
+
"STRATEGY_REQUIRED",
|
|
13
|
+
"Authentication strategy is required",
|
|
14
|
+
400
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
if (!identifier) {
|
|
18
|
+
return createApiSuccessResponse({
|
|
19
|
+
status: "needs_identifier",
|
|
20
|
+
strategy,
|
|
21
|
+
message: "Identifier is required to continue"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (strategy === "email_code") {
|
|
25
|
+
return await processEmailCodeStrategy(identifier);
|
|
26
|
+
}
|
|
27
|
+
if (strategy === "password") {
|
|
28
|
+
return await processPasswordStrategy(identifier);
|
|
29
|
+
}
|
|
30
|
+
if (strategy === "phone_code") {
|
|
31
|
+
return processPhoneCodeStrategy(identifier);
|
|
32
|
+
}
|
|
33
|
+
if (strategy === "reset_password_email_code" || strategy === "reset_password_phone_code") {
|
|
34
|
+
return await processResetPasswordStrategy(strategy, identifier);
|
|
35
|
+
}
|
|
36
|
+
return createApiErrorResponse(
|
|
37
|
+
"INVALID_STRATEGY",
|
|
38
|
+
`Unsupported authentication strategy: ${strategy}`,
|
|
39
|
+
400
|
|
40
|
+
);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
return createApiErrorResponse(
|
|
43
|
+
"SIGN_IN_CREATE_ERROR",
|
|
44
|
+
error instanceof Error ? error.message : "An error occurred while creating sign-in",
|
|
45
|
+
500
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const processEmailCodeStrategy = async (email) => {
|
|
50
|
+
try {
|
|
51
|
+
const retrieveUser = RetrieveUser();
|
|
52
|
+
const { data: user, error } = await retrieveUser.getUserByEmail(email);
|
|
53
|
+
if (error) {
|
|
54
|
+
return createApiErrorResponse(
|
|
55
|
+
error.code,
|
|
56
|
+
error.message,
|
|
57
|
+
400
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (!user.emailVerified) {
|
|
61
|
+
return createApiSuccessResponse({
|
|
62
|
+
status: "needs_email_verification",
|
|
63
|
+
identifier: email,
|
|
64
|
+
supportedFirstFactors: [{ strategy: "email_code" }],
|
|
65
|
+
userId: user.uid,
|
|
66
|
+
message: "Email verification required"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return createApiSuccessResponse({
|
|
70
|
+
status: "needs_first_factor",
|
|
71
|
+
identifier: email,
|
|
72
|
+
supportedFirstFactors: [{ strategy: "email_code" }],
|
|
73
|
+
userId: user.uid,
|
|
74
|
+
message: "User verified. Proceed with first factor authentication"
|
|
75
|
+
});
|
|
76
|
+
} catch (error) {
|
|
77
|
+
if (error instanceof Error && error.message.includes("no user record")) {
|
|
78
|
+
return createApiErrorResponse(
|
|
79
|
+
"USER_NOT_FOUND",
|
|
80
|
+
"No user found with this email address",
|
|
81
|
+
404
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
return createApiErrorResponse(
|
|
85
|
+
"EMAIL_VERIFICATION_ERROR",
|
|
86
|
+
error instanceof Error ? error.message : "Failed to verify email",
|
|
87
|
+
500
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const processPasswordStrategy = async (identifier) => {
|
|
92
|
+
try {
|
|
93
|
+
const retrieveUser = RetrieveUser();
|
|
94
|
+
const { data: user, error } = await retrieveUser.getUserByEmail(identifier);
|
|
95
|
+
if (error) {
|
|
96
|
+
return createApiErrorResponse(
|
|
97
|
+
error.code,
|
|
98
|
+
error.message,
|
|
99
|
+
400
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return createApiSuccessResponse({
|
|
103
|
+
status: "needs_first_factor",
|
|
104
|
+
identifier,
|
|
105
|
+
supportedFirstFactors: [{ strategy: "password" }],
|
|
106
|
+
userId: user.uid,
|
|
107
|
+
message: "User verified. Proceed with password authentication"
|
|
108
|
+
});
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (error instanceof Error && error.message.includes("no user record")) {
|
|
111
|
+
return createApiErrorResponse(
|
|
112
|
+
"USER_NOT_FOUND",
|
|
113
|
+
"No user found with this identifier",
|
|
114
|
+
404
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return createApiErrorResponse(
|
|
118
|
+
"USER_VERIFICATION_ERROR",
|
|
119
|
+
error instanceof Error ? error.message : "Failed to verify user",
|
|
120
|
+
500
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const processPhoneCodeStrategy = async (phoneNumber) => {
|
|
125
|
+
try {
|
|
126
|
+
return createApiSuccessResponse({
|
|
127
|
+
status: "needs_first_factor",
|
|
128
|
+
identifier: phoneNumber,
|
|
129
|
+
supportedFirstFactors: [{ strategy: "phone_code" }],
|
|
130
|
+
//userId: user.uid,
|
|
131
|
+
message: "User verified. Proceed with phone authentication"
|
|
132
|
+
});
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (error instanceof Error && error.message.includes("no user record")) {
|
|
135
|
+
return createApiErrorResponse(
|
|
136
|
+
"USER_NOT_FOUND",
|
|
137
|
+
"No user found with this phone number",
|
|
138
|
+
404
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
return createApiErrorResponse(
|
|
142
|
+
"PHONE_VERIFICATION_ERROR",
|
|
143
|
+
error instanceof Error ? error.message : "Failed to verify phone number",
|
|
144
|
+
500
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const processResetPasswordStrategy = async (strategy, identifier) => {
|
|
149
|
+
try {
|
|
150
|
+
if (strategy === "reset_password_email_code") {
|
|
151
|
+
const retrieveUser = RetrieveUser();
|
|
152
|
+
const { data: user, error } = await retrieveUser.getUserByEmail(identifier);
|
|
153
|
+
if (error) {
|
|
154
|
+
return createApiErrorResponse(
|
|
155
|
+
error.code,
|
|
156
|
+
error.message,
|
|
157
|
+
400
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
return createApiSuccessResponse({
|
|
161
|
+
status: "needs_first_factor",
|
|
162
|
+
identifier,
|
|
163
|
+
strategy,
|
|
164
|
+
userId: user.uid,
|
|
165
|
+
message: "User verified. Proceed with password reset"
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return createApiErrorResponse(
|
|
169
|
+
"NOT_IMPLEMENTED",
|
|
170
|
+
"Phone reset password strategy not yet implemented",
|
|
171
|
+
501
|
|
172
|
+
);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
return createApiErrorResponse(
|
|
175
|
+
"RESET_PASSWORD_ERROR",
|
|
176
|
+
error instanceof Error ? error.message : "Failed to process password reset",
|
|
177
|
+
500
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
export {
|
|
182
|
+
processEmailCodeStrategy,
|
|
183
|
+
processPasswordStrategy,
|
|
184
|
+
processPhoneCodeStrategy,
|
|
185
|
+
processResetPasswordStrategy,
|
|
186
|
+
processSignInCreate
|
|
187
|
+
};
|
|
188
|
+
//# sourceMappingURL=signInCreateHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/signInCreateHandler.ts"],"sourcesContent":["import type { SignInCreateParams } from '@tern-secure/types';\n\nimport { RetrieveUser } from './actions';\nimport type { RequestProcessorContext } from './c-authenticateRequestProcessor';\nimport {\n createApiErrorResponse,\n createApiSuccessResponse,\n} from './responses';\n\n\nexport const processSignInCreate = async (\n context: RequestProcessorContext\n): Promise<Response> => {\n try {\n const body = await context.request.json();\n const { strategy, identifier } = body as SignInCreateParams & { identifier?: string; password?: string };\n\n if (!strategy) {\n return createApiErrorResponse(\n 'STRATEGY_REQUIRED',\n 'Authentication strategy is required',\n 400\n );\n }\n\n if (!identifier) {\n return createApiSuccessResponse({\n status: 'needs_identifier',\n strategy,\n message: 'Identifier is required to continue',\n });\n }\n\n if (strategy === 'email_code') {\n return await processEmailCodeStrategy(identifier);\n }\n\n if (strategy === 'password') {\n return await processPasswordStrategy(identifier);\n }\n\n if (strategy === 'phone_code') {\n return processPhoneCodeStrategy(identifier);\n }\n\n if (strategy === 'reset_password_email_code' || strategy === 'reset_password_phone_code') {\n return await processResetPasswordStrategy(strategy, identifier);\n }\n\n return createApiErrorResponse(\n 'INVALID_STRATEGY',\n `Unsupported authentication strategy: ${strategy}`,\n 400\n );\n } catch (error) {\n return createApiErrorResponse(\n 'SIGN_IN_CREATE_ERROR',\n error instanceof Error\n ? error.message\n : 'An error occurred while creating sign-in',\n 500\n );\n }\n};\n\n/**\n * Processes email_code strategy\n * Verifies if user exists by email and returns needs_first_factor status\n */\nexport const processEmailCodeStrategy = async (email: string): Promise<Response> => {\n try {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(email);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n if (!user.emailVerified) {\n return createApiSuccessResponse({\n status: 'needs_email_verification',\n identifier: email,\n supportedFirstFactors: [{ strategy: 'email_code' }],\n userId: user.uid,\n message: 'Email verification required',\n });\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier: email,\n supportedFirstFactors: [{ strategy: 'email_code' }],\n userId: user.uid,\n message: 'User verified. Proceed with first factor authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this email address',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'EMAIL_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify email',\n 500\n );\n }\n};\n\n\nexport const processPasswordStrategy = async (identifier: string): Promise<Response> => {\n try {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(identifier);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier,\n supportedFirstFactors: [{ strategy: 'password' }],\n userId: user.uid,\n message: 'User verified. Proceed with password authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this identifier',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'USER_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify user',\n 500\n );\n }\n};\n\n\nexport const processPhoneCodeStrategy = async (phoneNumber: string): Promise<Response> => {\n try {\n //const retrieveUser = RetrieveUser();\n //const { data: user, error } = await retrieveUser.getUserByPhoneNumber(phoneNumber);\n\n //if (error) {\n // return createApiErrorResponse(\n // error.code,\n // error.message,\n // 400\n // );\n // }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier: phoneNumber,\n supportedFirstFactors: [{ strategy: 'phone_code' }],\n //userId: user.uid,\n message: 'User verified. Proceed with phone authentication',\n });\n } catch (error) {\n if (error instanceof Error && error.message.includes('no user record')) {\n return createApiErrorResponse(\n 'USER_NOT_FOUND',\n 'No user found with this phone number',\n 404\n );\n }\n\n return createApiErrorResponse(\n 'PHONE_VERIFICATION_ERROR',\n error instanceof Error ? error.message : 'Failed to verify phone number',\n 500\n );\n }\n};\n\n\nexport const processResetPasswordStrategy = async (\n strategy: 'reset_password_email_code' | 'reset_password_phone_code',\n identifier: string\n): Promise<Response> => {\n try {\n if (strategy === 'reset_password_email_code') {\n const retrieveUser = RetrieveUser();\n const { data: user, error } = await retrieveUser.getUserByEmail(identifier);\n\n if (error) {\n return createApiErrorResponse(\n error.code,\n error.message,\n 400\n );\n }\n\n return createApiSuccessResponse({\n status: 'needs_first_factor',\n identifier,\n strategy,\n userId: user.uid,\n message: 'User verified. Proceed with password reset',\n });\n }\n\n return createApiErrorResponse(\n 'NOT_IMPLEMENTED',\n 'Phone reset password strategy not yet implemented',\n 501\n );\n } catch (error) {\n return createApiErrorResponse(\n 'RESET_PASSWORD_ERROR',\n error instanceof Error ? error.message : 'Failed to process password reset',\n 500\n );\n }\n};\n"],"mappings":"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","names":[]}
|
|
@@ -6,7 +6,16 @@ const DEFAULT_CORS_OPTIONS = {
|
|
|
6
6
|
maxAge: 86400
|
|
7
7
|
// 24 hours
|
|
8
8
|
};
|
|
9
|
-
const
|
|
9
|
+
const DEFAULT_SESSION_COOKIE_OPTIONS = {
|
|
10
|
+
httpOnly: true,
|
|
11
|
+
path: "/",
|
|
12
|
+
secure: process.env.NODE_ENV === "production",
|
|
13
|
+
sameSite: "strict",
|
|
14
|
+
maxAge: 12 * 60 * 60 * 24,
|
|
15
|
+
// twelve days
|
|
16
|
+
priority: "high"
|
|
17
|
+
};
|
|
18
|
+
const DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS = {
|
|
10
19
|
httpOnly: true,
|
|
11
20
|
path: "/",
|
|
12
21
|
secure: process.env.NODE_ENV === "production",
|
|
@@ -113,9 +122,19 @@ const DEFAULT_SESSIONS_CONFIG = {
|
|
|
113
122
|
}
|
|
114
123
|
}
|
|
115
124
|
};
|
|
125
|
+
const DEFAULT_SIGNINS_CONFIG = {
|
|
126
|
+
...DEFAULT_ENDPOINT_CONFIG,
|
|
127
|
+
subEndpoints: {
|
|
128
|
+
resetPasswordEmail: {
|
|
129
|
+
enabled: true,
|
|
130
|
+
methods: ["POST"],
|
|
131
|
+
requireAuth: false
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
116
135
|
const DEFAULT_HANDLER_OPTIONS = {
|
|
117
136
|
cors: DEFAULT_CORS_OPTIONS,
|
|
118
|
-
cookies:
|
|
137
|
+
cookies: DEFAULT_SESSION_COOKIE_OPTIONS,
|
|
119
138
|
rateLimit: {
|
|
120
139
|
windowMs: 15 * 60 * 1e3,
|
|
121
140
|
// 15 minutes
|
|
@@ -126,7 +145,8 @@ const DEFAULT_HANDLER_OPTIONS = {
|
|
|
126
145
|
security: DEFAULT_SECURITY_OPTIONS,
|
|
127
146
|
endpoints: {
|
|
128
147
|
cookies: DEFAULT_COOKIE_REQUEST_CONFIG,
|
|
129
|
-
sessions: DEFAULT_SESSIONS_CONFIG
|
|
148
|
+
sessions: DEFAULT_SESSIONS_CONFIG,
|
|
149
|
+
signIns: DEFAULT_SIGNINS_CONFIG
|
|
130
150
|
},
|
|
131
151
|
tenantId: "",
|
|
132
152
|
revokeRefreshTokensOnSignOut: true,
|
|
@@ -149,13 +169,11 @@ class CookieUtils {
|
|
|
149
169
|
};
|
|
150
170
|
}
|
|
151
171
|
static getSessionConfig(cookieOptions) {
|
|
152
|
-
const sessionConfig = cookieOptions.session || {};
|
|
153
|
-
const defaultSession = DEFAULT_COOKIE_OPTIONS.session || {};
|
|
154
172
|
return {
|
|
155
|
-
path:
|
|
156
|
-
httpOnly:
|
|
157
|
-
sameSite:
|
|
158
|
-
maxAge:
|
|
173
|
+
path: cookieOptions.path ?? "/",
|
|
174
|
+
httpOnly: cookieOptions.httpOnly ?? true,
|
|
175
|
+
sameSite: cookieOptions.sameSite ?? "lax",
|
|
176
|
+
maxAge: cookieOptions.maxAge ?? 3600 * 24 * 7
|
|
159
177
|
};
|
|
160
178
|
}
|
|
161
179
|
static getFixedTokenConfig(tokenType) {
|
|
@@ -175,13 +193,15 @@ class CookieUtils {
|
|
|
175
193
|
}
|
|
176
194
|
export {
|
|
177
195
|
CookieUtils,
|
|
178
|
-
DEFAULT_COOKIE_OPTIONS,
|
|
179
196
|
DEFAULT_COOKIE_REQUEST_CONFIG,
|
|
180
197
|
DEFAULT_CORS_OPTIONS,
|
|
181
198
|
DEFAULT_ENDPOINT_CONFIG,
|
|
182
199
|
DEFAULT_HANDLER_OPTIONS,
|
|
200
|
+
DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS,
|
|
183
201
|
DEFAULT_SECURITY_OPTIONS,
|
|
184
202
|
DEFAULT_SESSIONS_CONFIG,
|
|
203
|
+
DEFAULT_SESSION_COOKIE_OPTIONS,
|
|
204
|
+
DEFAULT_SIGNINS_CONFIG,
|
|
185
205
|
FIXED_TOKEN_CONFIGS
|
|
186
206
|
};
|
|
187
207
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/admin/types.ts"],"sourcesContent":["import type {\n AuthEndpoint,\n CookieEndpointConfig,\n CookieOpts as CookieOptions,\n CorsOptions,\n EndpointConfig,\n SecurityOptions,\n SessionEndpointConfig,\n SessionSubEndpoint,\n TernSecureHandlerOptions,\n TokenCookieConfig
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/admin/types.ts"],"sourcesContent":["import type {\n AuthEndpoint,\n CookieEndpointConfig,\n CookieOpts as CookieOptions,\n CorsOptions,\n EndpointConfig,\n SecurityOptions,\n SessionEndpointConfig,\n SessionSubEndpoint,\n SignInEndpointConfig,\n SignInSubEndpoint,\n TernSecureHandlerOptions,\n TokenCookieConfig\n} from '@tern-secure/types';\nimport { type NextResponse } from 'next/server';\n\nexport const DEFAULT_CORS_OPTIONS: CorsOptions = {\n allowedOrigins: [],\n allowedMethods: ['GET', 'POST'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n allowCredentials: true,\n maxAge: 86400, // 24 hours\n};\n\nexport const DEFAULT_SESSION_COOKIE_OPTIONS: CookieOptions = {\n httpOnly: true,\n path: '/',\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 12 * 60 * 60 * 24, // twelve days\n priority: 'high',\n};\n\nexport const DEFAULT_ID_REFRESH_TOKEN_COOKIE_OPTIONS: CookieOptions = {\n httpOnly: true,\n path: '/',\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: 12 * 60 * 60 * 24, // twelve days\n priority: 'high',\n};\n\n\nexport const FIXED_TOKEN_CONFIGS = {\n id: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600, // 1 hour\n },\n refresh: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 30, // 30 days (changes when user events occur)\n },\n signature: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 7, // 1 week (as needed)\n },\n custom: {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n maxAge: 3600 * 24 * 7, // 1 week (as needed)\n },\n} as const;\n\nexport const DEFAULT_SECURITY_OPTIONS: SecurityOptions = {\n requireCSRF: true,\n allowedReferers: [],\n requiredHeaders: {},\n ipWhitelist: [],\n userAgent: {\n block: [],\n allow: [],\n },\n};\n\nexport const DEFAULT_ENDPOINT_CONFIG: EndpointConfig = {\n enabled: true,\n methods: ['GET', 'POST'],\n requireAuth: false,\n security: DEFAULT_SECURITY_OPTIONS,\n};\n\nexport const DEFAULT_COOKIE_REQUEST_CONFIG: CookieEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n get: {\n enabled: true,\n methods: ['GET'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n allowedReferers: [],\n },\n },\n },\n};\n\nexport const DEFAULT_SESSIONS_CONFIG: SessionEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n verify: {\n enabled: true,\n methods: ['GET'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n allowedReferers: [],\n },\n },\n createsession: {\n enabled: true,\n methods: ['POST'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n },\n },\n refresh: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n revoke: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n },\n};\n\nexport const DEFAULT_SIGNINS_CONFIG: SignInEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n resetPasswordEmail: {\n enabled: true,\n methods: ['POST'],\n requireAuth: false\n },\n },\n};\n\nexport const DEFAULT_HANDLER_OPTIONS: Required<TernSecureHandlerOptions> & {\n endpoints: Required<NonNullable<TernSecureHandlerOptions['endpoints']>>;\n} = {\n cors: DEFAULT_CORS_OPTIONS,\n cookies: DEFAULT_SESSION_COOKIE_OPTIONS,\n rateLimit: {\n windowMs: 15 * 60 * 1000, // 15 minutes\n maxRequests: 100,\n skipSuccessful: false,\n skipFailedRequests: false,\n },\n security: DEFAULT_SECURITY_OPTIONS,\n endpoints: {\n cookies: DEFAULT_COOKIE_REQUEST_CONFIG,\n sessions: DEFAULT_SESSIONS_CONFIG,\n signIns: DEFAULT_SIGNINS_CONFIG,\n },\n tenantId: '',\n revokeRefreshTokensOnSignOut: true,\n enableCustomToken: false,\n debug: false,\n environment: 'production',\n basePath: '/api/auth',\n};\n\nexport interface ValidationResult {\n error?: NextResponse;\n data?: any;\n}\n\nexport interface ValidationConfig {\n cors?: CorsOptions;\n security?: SecurityOptions;\n endpoint?: {\n name: AuthEndpoint;\n config: EndpointConfig;\n };\n subEndpoint?: {\n name: SessionSubEndpoint;\n config: EndpointConfig;\n };\n requireIdToken?: boolean;\n requireCsrfToken?: boolean;\n}\n\nexport interface ComprehensiveValidationResult {\n isValid: boolean;\n error?: Response;\n corsResponse?: Response;\n sessionData?: {\n body: any;\n idToken?: string;\n csrfToken?: string;\n };\n}\n\nexport type suffix = 'session' | 'id' | 'refresh' | 'signature' | 'custom';\n\nexport class CookieUtils {\n static getCookieName(namePrefix: string, tokenType: suffix): string {\n return `${namePrefix}.${tokenType}`;\n }\n\n static getCookieNames(namePrefix: string) {\n return {\n session: this.getCookieName(namePrefix, 'session'),\n id: this.getCookieName(namePrefix, 'id'),\n refresh: this.getCookieName(namePrefix, 'refresh'),\n signature: this.getCookieName(namePrefix, 'signature'),\n custom: this.getCookieName(namePrefix, 'custom'),\n };\n }\n\n static getSessionConfig(cookieOptions: CookieOptions): TokenCookieConfig {\n return {\n path: cookieOptions.path ?? '/',\n httpOnly: cookieOptions.httpOnly ?? true,\n sameSite: cookieOptions.sameSite ?? 'lax',\n maxAge: cookieOptions.maxAge ?? 3600 * 24 * 7,\n };\n }\n\n static getFixedTokenConfig(\n tokenType: Exclude<suffix, 'session'>,\n ): TokenCookieConfig {\n const fixedConfig = FIXED_TOKEN_CONFIGS[tokenType];\n\n return {\n path: fixedConfig.path,\n httpOnly: fixedConfig.httpOnly,\n sameSite: fixedConfig.sameSite,\n maxAge: fixedConfig.maxAge,\n };\n }\n\n static validateSessionMaxAge(maxAge: number): boolean {\n const minAge = 300; // 5 minutes\n const maxAgeLimit = 3600 * 24 * 14; // 2 weeks\n return maxAge >= minAge && maxAge <= maxAgeLimit;\n }\n}\n\nexport {\n AuthEndpoint,\n CookieOptions,\n CorsOptions,\n SecurityOptions,\n SessionSubEndpoint,\n EndpointConfig,\n SessionEndpointConfig,\n SignInEndpointConfig,\n SignInSubEndpoint,\n TernSecureHandlerOptions,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { TernSecureProvider as TernSecureReactProvider } from "@tern-secure/react";
|
|
4
4
|
import { TernNextOptionsProvider, useTernNextOptions } from "../../boundary/NextOptionsCtx";
|
|
5
5
|
import { allNextProviderPropsWithEnv } from "../../utils/allNextProviderProps";
|
|
6
|
+
import { TernUIScript } from "../../utils/tern-ui-script";
|
|
6
7
|
import { useAwaitablePush } from "./useAwaitablePush";
|
|
7
8
|
import { useAwaitableReplace } from "./useAwaitableReplace";
|
|
8
9
|
const NextClientProvider = (props) => {
|
|
@@ -20,7 +21,10 @@ const NextClientProvider = (props) => {
|
|
|
20
21
|
// @ts-expect-error Error because of the stricter types of internal `replace`
|
|
21
22
|
routerReplace: replace
|
|
22
23
|
});
|
|
23
|
-
return /* @__PURE__ */ jsx(TernNextOptionsProvider, { options: providerProps, children: /* @__PURE__ */
|
|
24
|
+
return /* @__PURE__ */ jsx(TernNextOptionsProvider, { options: providerProps, children: /* @__PURE__ */ jsxs(TernSecureReactProvider, { ...providerProps, children: [
|
|
25
|
+
children,
|
|
26
|
+
/* @__PURE__ */ jsx(TernUIScript, { router: "app" })
|
|
27
|
+
] }) });
|
|
24
28
|
};
|
|
25
29
|
const ClientTernSecureProvider = (props) => {
|
|
26
30
|
const { children, ...rest } = props;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/app-router/client/TernSecureProvider.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { TernSecureProvider as TernSecureReactProvider } from '@tern-secure/react';\r\n\r\nimport { TernNextOptionsProvider, useTernNextOptions } from '../../boundary/NextOptionsCtx';\r\nimport type { TernSecureNextProps } from '../../types';\r\nimport { allNextProviderPropsWithEnv } from '../../utils/allNextProviderProps';\r\nimport { useAwaitablePush } from './useAwaitablePush';\r\nimport { useAwaitableReplace } from './useAwaitableReplace';\r\n\r\nconst NextClientProvider = (props: TernSecureNextProps) => {\r\n const { children } = props;\r\n\r\n const push = useAwaitablePush();\r\n const replace = useAwaitableReplace();\r\n\r\n const isNested = Boolean(useTernNextOptions());\r\n if (isNested) {\r\n return props.children;\r\n }\r\n\r\n const providerProps = allNextProviderPropsWithEnv({\r\n ...props,\r\n // @ts-expect-error Error because of the stricter types of internal `push`\r\n routerPush: push,\r\n // @ts-expect-error Error because of the stricter types of internal `replace`\r\n routerReplace: replace,\r\n });\r\n return (\r\n <TernNextOptionsProvider options={providerProps}>\r\n <TernSecureReactProvider {...providerProps}
|
|
1
|
+
{"version":3,"sources":["../../../../src/app-router/client/TernSecureProvider.tsx"],"sourcesContent":["'use client';\r\n\r\nimport { TernSecureProvider as TernSecureReactProvider } from '@tern-secure/react';\r\n\r\nimport { TernNextOptionsProvider, useTernNextOptions } from '../../boundary/NextOptionsCtx';\r\nimport type { TernSecureNextProps } from '../../types';\r\nimport { allNextProviderPropsWithEnv } from '../../utils/allNextProviderProps';\r\nimport { TernUIScript } from '../../utils/tern-ui-script';\r\nimport { useAwaitablePush } from './useAwaitablePush';\r\nimport { useAwaitableReplace } from './useAwaitableReplace';\r\n\r\nconst NextClientProvider = (props: TernSecureNextProps) => {\r\n const { children } = props;\r\n\r\n const push = useAwaitablePush();\r\n const replace = useAwaitableReplace();\r\n\r\n const isNested = Boolean(useTernNextOptions());\r\n if (isNested) {\r\n return props.children;\r\n }\r\n\r\n const providerProps = allNextProviderPropsWithEnv({\r\n ...props,\r\n // @ts-expect-error Error because of the stricter types of internal `push`\r\n routerPush: push,\r\n // @ts-expect-error Error because of the stricter types of internal `replace`\r\n routerReplace: replace,\r\n });\r\n return (\r\n <TernNextOptionsProvider options={providerProps}>\r\n <TernSecureReactProvider {...providerProps}>\r\n {children}\r\n <TernUIScript router=\"app\" />\r\n </TernSecureReactProvider>\r\n </TernNextOptionsProvider>\r\n );\r\n};\r\n\r\nexport const ClientTernSecureProvider = (props: TernSecureNextProps) => {\r\n const { children, ...rest } = props;\r\n return <NextClientProvider {...rest}>{children}</NextClientProvider>;\r\n};\r\n"],"mappings":";AA+BM,SAEE,KAFF;AA7BN,SAAS,sBAAsB,+BAA+B;AAE9D,SAAS,yBAAyB,0BAA0B;AAE5D,SAAS,mCAAmC;AAC5C,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AACjC,SAAS,2BAA2B;AAEpC,MAAM,qBAAqB,CAAC,UAA+B;AACzD,QAAM,EAAE,SAAS,IAAI;AAErB,QAAM,OAAO,iBAAiB;AAC9B,QAAM,UAAU,oBAAoB;AAEpC,QAAM,WAAW,QAAQ,mBAAmB,CAAC;AAC7C,MAAI,UAAU;AACZ,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,gBAAgB,4BAA4B;AAAA,IAChD,GAAG;AAAA;AAAA,IAEH,YAAY;AAAA;AAAA,IAEZ,eAAe;AAAA,EACjB,CAAC;AACD,SACE,oBAAC,2BAAwB,SAAS,eAChC,+BAAC,2BAAyB,GAAG,eAC1B;AAAA;AAAA,IACD,oBAAC,gBAAa,QAAO,OAAM;AAAA,KAC7B,GACF;AAEJ;AAEO,MAAM,2BAA2B,CAAC,UAA+B;AACtE,QAAM,EAAE,UAAU,GAAG,KAAK,IAAI;AAC9B,SAAO,oBAAC,sBAAoB,GAAG,MAAO,UAAS;AACjD;","names":[]}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { PromiseAuthProvider } from "../../boundary/PromiseAuthProvider";
|
|
4
|
-
import {
|
|
4
|
+
import { getTernSecureAuthData } from "../../server/data/getAuthDataFromRequest";
|
|
5
5
|
import { isNext13 } from "../../server/sdk-versions";
|
|
6
6
|
import { allNextProviderPropsWithEnv } from "../../utils/allNextProviderProps";
|
|
7
7
|
import { ClientTernSecureProvider } from "../client/TernSecureProvider";
|
|
8
8
|
import { buildRequestLike } from "./utils";
|
|
9
9
|
const getTernSecureState = React.cache(async function getTernSecureState2() {
|
|
10
10
|
const request = await buildRequestLike();
|
|
11
|
-
const data =
|
|
11
|
+
const data = getTernSecureAuthData(request);
|
|
12
12
|
return data;
|
|
13
13
|
});
|
|
14
14
|
async function TernSecureProvider(props) {
|