@tern-secure/backend 1.2.0-canary.v20251125170702 → 1.2.0-canary.v20251127235234
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/admin/index.js +3 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +4 -2
- package/dist/admin/index.mjs.map +1 -1
- package/dist/auth/constants.d.ts +6 -0
- package/dist/auth/constants.d.ts.map +1 -0
- package/dist/auth/credential.d.ts +27 -0
- package/dist/auth/credential.d.ts.map +1 -0
- package/dist/auth/getauth.d.ts +1 -0
- package/dist/auth/getauth.d.ts.map +1 -1
- package/dist/auth/index.js +234 -28
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/index.mjs +3 -3
- package/dist/auth/utils.d.ts +3 -0
- package/dist/auth/utils.d.ts.map +1 -0
- package/dist/{chunk-MS6L7M3C.mjs → chunk-DJLDUW7J.mjs} +174 -12
- package/dist/chunk-DJLDUW7J.mjs.map +1 -0
- package/dist/{chunk-ASGV4MFO.mjs → chunk-GFH5CXQR.mjs} +2 -2
- package/dist/{chunk-DDUNOEIM.mjs → chunk-NXYWC6YO.mjs} +278 -116
- package/dist/chunk-NXYWC6YO.mjs.map +1 -0
- package/dist/{chunk-DFAJCSBJ.mjs → chunk-WIVOBOZR.mjs} +2 -1
- package/dist/chunk-WIVOBOZR.mjs.map +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/fireRestApi/createFireApi.d.ts +2 -1
- package/dist/fireRestApi/createFireApi.d.ts.map +1 -1
- package/dist/fireRestApi/endpoints/AppCheckApi.d.ts +23 -0
- package/dist/fireRestApi/endpoints/AppCheckApi.d.ts.map +1 -0
- package/dist/fireRestApi/endpoints/TokenApi.d.ts +3 -1
- package/dist/fireRestApi/endpoints/TokenApi.d.ts.map +1 -1
- package/dist/fireRestApi/endpoints/UserData.d.ts.map +1 -1
- package/dist/fireRestApi/endpoints/index.d.ts +1 -0
- package/dist/fireRestApi/endpoints/index.d.ts.map +1 -1
- package/dist/fireRestApi/request.d.ts.map +1 -1
- package/dist/index.js +390 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +161 -14
- package/dist/index.mjs.map +1 -1
- package/dist/jwt/index.d.ts +1 -0
- package/dist/jwt/index.d.ts.map +1 -1
- package/dist/jwt/index.js +51 -19
- package/dist/jwt/index.js.map +1 -1
- package/dist/jwt/index.mjs +8 -132
- package/dist/jwt/index.mjs.map +1 -1
- package/dist/jwt/signJwt.d.ts +8 -0
- package/dist/jwt/signJwt.d.ts.map +1 -1
- package/dist/jwt/verifyJwt.d.ts.map +1 -1
- package/dist/tokens/authstate.d.ts.map +1 -1
- package/dist/tokens/c-authenticateRequestProcessor.d.ts +1 -0
- package/dist/tokens/c-authenticateRequestProcessor.d.ts.map +1 -1
- package/dist/tokens/request.d.ts.map +1 -1
- package/dist/tokens/types.d.ts +2 -1
- package/dist/tokens/types.d.ts.map +1 -1
- package/dist/tokens/verify.d.ts +2 -2
- package/dist/tokens/verify.d.ts.map +1 -1
- package/dist/utils/admin-init.d.ts +1 -0
- package/dist/utils/admin-init.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-DDUNOEIM.mjs.map +0 -1
- package/dist/chunk-DFAJCSBJ.mjs.map +0 -1
- package/dist/chunk-MS6L7M3C.mjs.map +0 -1
- /package/dist/{chunk-ASGV4MFO.mjs.map → chunk-GFH5CXQR.mjs.map} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createTernSecureRequest
|
|
3
|
-
} from "./chunk-ASGV4MFO.mjs";
|
|
4
1
|
import {
|
|
5
2
|
getAuth,
|
|
6
3
|
verifyToken
|
|
7
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-DJLDUW7J.mjs";
|
|
5
|
+
import {
|
|
6
|
+
createTernSecureRequest
|
|
7
|
+
} from "./chunk-GFH5CXQR.mjs";
|
|
8
8
|
import {
|
|
9
9
|
constants
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WIVOBOZR.mjs";
|
|
11
11
|
import {
|
|
12
12
|
RefreshTokenErrorReason,
|
|
13
13
|
TokenVerificationError,
|
|
14
14
|
TokenVerificationErrorReason,
|
|
15
15
|
mapJwtPayloadToDecodedIdToken,
|
|
16
16
|
ternDecodeJwt
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-NXYWC6YO.mjs";
|
|
18
18
|
|
|
19
19
|
// src/createRedirect.ts
|
|
20
20
|
var buildUrl = (_baseUrl, _targetUrl, _returnBackUrl) => {
|
|
@@ -201,6 +201,84 @@ var AbstractAPI = class {
|
|
|
201
201
|
}
|
|
202
202
|
};
|
|
203
203
|
|
|
204
|
+
// src/fireRestApi/endpoints/AppCheckApi.ts
|
|
205
|
+
function getSdkVersion() {
|
|
206
|
+
return "12.7.0";
|
|
207
|
+
}
|
|
208
|
+
var FIREBASE_APP_CHECK_CONFIG_HEADERS = {
|
|
209
|
+
"X-Firebase-Client": `fire-admin-node/${getSdkVersion()}`
|
|
210
|
+
};
|
|
211
|
+
var AppCheckApi = class extends AbstractAPI {
|
|
212
|
+
async exchangeCustomToken(params) {
|
|
213
|
+
const { projectId, appId, customToken, accessToken, limitedUse = false } = params;
|
|
214
|
+
if (!projectId || !appId) {
|
|
215
|
+
throw new Error("Project ID and App ID are required for App Check token exchange");
|
|
216
|
+
}
|
|
217
|
+
const endpoint = `https://firebaseappcheck.googleapis.com/v1beta/projects/${projectId}/apps/${appId}:exchangeCustomToken`;
|
|
218
|
+
const headers = {
|
|
219
|
+
"Content-Type": "application/json",
|
|
220
|
+
"Authorization": `Bearer ${accessToken}`
|
|
221
|
+
};
|
|
222
|
+
const body = {
|
|
223
|
+
customToken,
|
|
224
|
+
limitedUse
|
|
225
|
+
};
|
|
226
|
+
try {
|
|
227
|
+
const response = await fetch(endpoint, {
|
|
228
|
+
method: "POST",
|
|
229
|
+
headers,
|
|
230
|
+
body: JSON.stringify(body)
|
|
231
|
+
});
|
|
232
|
+
if (!response.ok) {
|
|
233
|
+
const errorText = await response.text();
|
|
234
|
+
throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);
|
|
235
|
+
}
|
|
236
|
+
const data = await response.json();
|
|
237
|
+
return {
|
|
238
|
+
token: data.token,
|
|
239
|
+
ttl: data.ttl
|
|
240
|
+
};
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.warn("[ternsecure - appcheck api]unexpected error:", error);
|
|
243
|
+
throw error;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
async exchangeDebugToken(params) {
|
|
247
|
+
const { projectId, appId, customToken, accessToken, limitedUse = false } = params;
|
|
248
|
+
if (!projectId || !appId) {
|
|
249
|
+
throw new Error("Project ID and App ID are required for App Check token exchange");
|
|
250
|
+
}
|
|
251
|
+
const endpoint = `https://firebaseappcheck.googleapis.com/v1beta/projects/${projectId}/apps/${appId}:exchangeDebugToken`;
|
|
252
|
+
const headers = {
|
|
253
|
+
...FIREBASE_APP_CHECK_CONFIG_HEADERS,
|
|
254
|
+
"Authorization": `Bearer ${accessToken}`
|
|
255
|
+
};
|
|
256
|
+
const body = {
|
|
257
|
+
customToken,
|
|
258
|
+
limitedUse
|
|
259
|
+
};
|
|
260
|
+
try {
|
|
261
|
+
const response = await fetch(endpoint, {
|
|
262
|
+
method: "POST",
|
|
263
|
+
headers,
|
|
264
|
+
body: JSON.stringify(body)
|
|
265
|
+
});
|
|
266
|
+
if (!response.ok) {
|
|
267
|
+
const errorText = await response.text();
|
|
268
|
+
throw new Error(`App Check token exchange failed: ${response.status} ${errorText}`);
|
|
269
|
+
}
|
|
270
|
+
const data = await response.json();
|
|
271
|
+
return {
|
|
272
|
+
token: data.token,
|
|
273
|
+
ttl: data.ttl
|
|
274
|
+
};
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.warn("[ternsecure - appcheck api]unexpected error:", error);
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
204
282
|
// src/fireRestApi/endpoints/EmailApi.ts
|
|
205
283
|
var EmailApi = class extends AbstractAPI {
|
|
206
284
|
async verifyEmailVerification(apiKey, params) {
|
|
@@ -318,11 +396,14 @@ var SignUpApi = class extends AbstractAPI {
|
|
|
318
396
|
var TokenApi = class extends AbstractAPI {
|
|
319
397
|
async refreshToken(apiKey, params) {
|
|
320
398
|
this.requireApiKey(apiKey);
|
|
321
|
-
const { refresh_token, request_origin, ...restParams } = params;
|
|
399
|
+
const { refresh_token, request_origin, app_check_token, ...restParams } = params;
|
|
322
400
|
const headers = {};
|
|
323
401
|
if (request_origin) {
|
|
324
402
|
headers["Referer"] = request_origin;
|
|
325
403
|
}
|
|
404
|
+
if (app_check_token) {
|
|
405
|
+
headers["X-Firebase-AppCheck"] = app_check_token;
|
|
406
|
+
}
|
|
326
407
|
const bodyParams = {
|
|
327
408
|
grant_type: "refresh_token",
|
|
328
409
|
refresh_token,
|
|
@@ -342,13 +423,23 @@ var TokenApi = class extends AbstractAPI {
|
|
|
342
423
|
if (options?.referer) {
|
|
343
424
|
headers["Referer"] = options.referer;
|
|
344
425
|
}
|
|
345
|
-
|
|
426
|
+
if (options?.appCheckToken) {
|
|
427
|
+
headers["X-Firebase-AppCheck"] = options.appCheckToken;
|
|
428
|
+
}
|
|
429
|
+
const response = await this.request({
|
|
346
430
|
endpoint: "signInWithCustomToken",
|
|
347
431
|
method: "POST",
|
|
348
432
|
apiKey,
|
|
349
433
|
bodyParams: params,
|
|
350
434
|
headerParams: headers
|
|
351
435
|
});
|
|
436
|
+
if (response.errors) {
|
|
437
|
+
throw new Error(response.errors[0].message);
|
|
438
|
+
}
|
|
439
|
+
if (!response.data) {
|
|
440
|
+
throw new Error("No data received from Firebase token exchange");
|
|
441
|
+
}
|
|
442
|
+
return response.data;
|
|
352
443
|
}
|
|
353
444
|
};
|
|
354
445
|
|
|
@@ -480,8 +571,18 @@ function createRequest(options) {
|
|
|
480
571
|
...body
|
|
481
572
|
});
|
|
482
573
|
}
|
|
483
|
-
const isJSONResponse = res?.headers && res.headers?.get(constants.Headers.ContentType)
|
|
484
|
-
|
|
574
|
+
const isJSONResponse = res?.headers && res.headers?.get(constants.Headers.ContentType)?.includes(constants.ContentTypes.Json);
|
|
575
|
+
let responseBody;
|
|
576
|
+
try {
|
|
577
|
+
const text = await res.text();
|
|
578
|
+
try {
|
|
579
|
+
responseBody = JSON.parse(text);
|
|
580
|
+
} catch {
|
|
581
|
+
responseBody = text;
|
|
582
|
+
}
|
|
583
|
+
} catch (e) {
|
|
584
|
+
responseBody = null;
|
|
585
|
+
}
|
|
485
586
|
if (!res.ok) {
|
|
486
587
|
return {
|
|
487
588
|
data: null,
|
|
@@ -562,6 +663,7 @@ function parseError(error) {
|
|
|
562
663
|
function createFireApi(options) {
|
|
563
664
|
const request = createRequest(options);
|
|
564
665
|
return {
|
|
666
|
+
appCheck: new AppCheckApi(request),
|
|
565
667
|
email: new EmailApi(request),
|
|
566
668
|
password: new PasswordApi(request),
|
|
567
669
|
signIn: new SignInApi(request),
|
|
@@ -615,6 +717,7 @@ var RequestProcessorContext = class {
|
|
|
615
717
|
this.userAgent = this.getHeader(constants.Headers.UserAgent);
|
|
616
718
|
this.secFetchDest = this.getHeader(constants.Headers.SecFetchDest);
|
|
617
719
|
this.accept = this.getHeader(constants.Headers.Accept);
|
|
720
|
+
this.appCheckToken = this.getHeader(constants.Headers.AppCheckToken);
|
|
618
721
|
}
|
|
619
722
|
initCookieValues() {
|
|
620
723
|
const isProduction = process.env.NODE_ENV === "production";
|
|
@@ -678,7 +781,7 @@ function isRequestForRefresh(error, context, request) {
|
|
|
678
781
|
}
|
|
679
782
|
async function authenticateRequest(request, options) {
|
|
680
783
|
const context = createRequestProcessor(createTernSecureRequest(request), options);
|
|
681
|
-
const { refreshTokenInCookie } = context;
|
|
784
|
+
const { refreshTokenInCookie, appCheckToken } = context;
|
|
682
785
|
const { refreshExpiredIdToken } = getAuth(options);
|
|
683
786
|
function checkSessionTimeout(authTimeValue) {
|
|
684
787
|
const defaultMaxAgeSeconds = convertToSeconds("5 days");
|
|
@@ -701,7 +804,8 @@ async function authenticateRequest(request, options) {
|
|
|
701
804
|
};
|
|
702
805
|
}
|
|
703
806
|
return await refreshExpiredIdToken(refreshTokenInCookie, {
|
|
704
|
-
referer: context.ternUrl.origin
|
|
807
|
+
referer: context.ternUrl.origin,
|
|
808
|
+
appCheckToken
|
|
705
809
|
});
|
|
706
810
|
}
|
|
707
811
|
async function handleRefresh() {
|
|
@@ -803,7 +907,24 @@ async function authenticateRequest(request, options) {
|
|
|
803
907
|
if (errors) {
|
|
804
908
|
throw errors[0];
|
|
805
909
|
}
|
|
806
|
-
const
|
|
910
|
+
const { exchangeAppCheckToken } = getAuth(options);
|
|
911
|
+
let appCheckTokenValue;
|
|
912
|
+
try {
|
|
913
|
+
const idToken = context.idTokenInCookie || "";
|
|
914
|
+
const appCheckResult = await exchangeAppCheckToken(idToken);
|
|
915
|
+
console.log("[authenticateRequest] App Check exchange result:", appCheckResult);
|
|
916
|
+
if (appCheckResult.data?.token) {
|
|
917
|
+
appCheckTokenValue = appCheckResult.data.token;
|
|
918
|
+
}
|
|
919
|
+
} catch (error) {
|
|
920
|
+
console.warn("App Check token exchange failed:", error);
|
|
921
|
+
}
|
|
922
|
+
const headers = new Headers();
|
|
923
|
+
headers.set(
|
|
924
|
+
constants.Headers.AppCheckToken,
|
|
925
|
+
appCheckTokenValue || ""
|
|
926
|
+
);
|
|
927
|
+
const signedInRequestState = signedIn(context, data, headers, context.idTokenInCookie);
|
|
807
928
|
return signedInRequestState;
|
|
808
929
|
} catch (err) {
|
|
809
930
|
return handleError(err, "cookie");
|
|
@@ -817,7 +938,23 @@ async function authenticateRequest(request, options) {
|
|
|
817
938
|
if (errors) {
|
|
818
939
|
throw errors[0];
|
|
819
940
|
}
|
|
820
|
-
const
|
|
941
|
+
const { exchangeAppCheckToken } = getAuth(options);
|
|
942
|
+
let appCheckTokenValue;
|
|
943
|
+
try {
|
|
944
|
+
const token = sessionTokenInHeader || "";
|
|
945
|
+
const appCheckResult = await exchangeAppCheckToken(token);
|
|
946
|
+
if (appCheckResult.data?.token) {
|
|
947
|
+
appCheckTokenValue = appCheckResult.data.token;
|
|
948
|
+
}
|
|
949
|
+
} catch (error) {
|
|
950
|
+
console.warn("App Check token exchange failed:", error);
|
|
951
|
+
}
|
|
952
|
+
const headers = new Headers();
|
|
953
|
+
headers.set(
|
|
954
|
+
constants.Headers.AppCheckToken,
|
|
955
|
+
appCheckTokenValue || ""
|
|
956
|
+
);
|
|
957
|
+
const signedInRequestState = signedIn(context, data, headers, sessionTokenInHeader);
|
|
821
958
|
return signedInRequestState;
|
|
822
959
|
} catch (err) {
|
|
823
960
|
return handleError(err, "header");
|
|
@@ -831,6 +968,16 @@ async function authenticateRequest(request, options) {
|
|
|
831
968
|
if (isRequestForRefresh(err, context, request)) {
|
|
832
969
|
const { data, error } = await handleRefresh();
|
|
833
970
|
if (data) {
|
|
971
|
+
const { exchangeAppCheckToken } = getAuth(options);
|
|
972
|
+
let appCheckTokenValue;
|
|
973
|
+
try {
|
|
974
|
+
const appCheckResult = await exchangeAppCheckToken(data.token);
|
|
975
|
+
if (appCheckResult.data?.token) {
|
|
976
|
+
appCheckTokenValue = appCheckResult.data.token;
|
|
977
|
+
}
|
|
978
|
+
} catch (error2) {
|
|
979
|
+
console.warn("App Check token exchange failed in error handler:", error2);
|
|
980
|
+
}
|
|
834
981
|
return signedIn(context, data.decoded, data.headers, data.token);
|
|
835
982
|
}
|
|
836
983
|
if (error?.cause?.reason) {
|