firebase-admin-edge 1.0.18 → 1.0.20
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/README.md +26 -0
- package/dist/auth/auth-endpoint-errors.d.ts +15 -0
- package/dist/auth/auth-endpoint-errors.d.ts.map +1 -0
- package/dist/auth/auth-endpoint-errors.js +120 -0
- package/dist/auth/auth-endpoint-errors.js.map +1 -0
- package/dist/auth/auth-error-codes.d.ts +777 -0
- package/dist/auth/auth-error-codes.d.ts.map +1 -0
- package/dist/auth/auth-error-codes.js +823 -0
- package/dist/auth/auth-error-codes.js.map +1 -0
- package/dist/auth/errors.d.ts +20 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +29 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/firebase-admin-auth.d.ts +12 -21
- package/dist/auth/firebase-admin-auth.d.ts.map +1 -1
- package/dist/auth/firebase-admin-auth.js +54 -16
- package/dist/auth/firebase-admin-auth.js.map +1 -1
- package/dist/auth/firebase-admin-auth.test.js +36 -24
- package/dist/auth/firebase-admin-auth.test.js.map +1 -1
- package/dist/auth/firebase-auth-endpoints.d.ts +13 -77
- package/dist/auth/firebase-auth-endpoints.d.ts.map +1 -1
- package/dist/auth/firebase-auth-endpoints.js +53 -37
- package/dist/auth/firebase-auth-endpoints.js.map +1 -1
- package/dist/auth/firebase-auth-endpoints.test.js +178 -13
- package/dist/auth/firebase-auth-endpoints.test.js.map +1 -1
- package/dist/auth/firebase-auth.d.ts +5 -9
- package/dist/auth/firebase-auth.d.ts.map +1 -1
- package/dist/auth/firebase-auth.js +61 -21
- package/dist/auth/firebase-auth.js.map +1 -1
- package/dist/auth/firebase-auth.test.js +29 -12
- package/dist/auth/firebase-auth.test.js.map +1 -1
- package/dist/auth/firebase-jwt.d.ts +5 -29
- package/dist/auth/firebase-jwt.d.ts.map +1 -1
- package/dist/auth/firebase-jwt.js +74 -33
- package/dist/auth/firebase-jwt.js.map +1 -1
- package/dist/auth/firebase-jwt.test.js +31 -11
- package/dist/auth/firebase-jwt.test.js.map +1 -1
- package/dist/auth/github-oauth.d.ts +5 -2
- package/dist/auth/github-oauth.d.ts.map +1 -1
- package/dist/auth/github-oauth.js +126 -13
- package/dist/auth/github-oauth.js.map +1 -1
- package/dist/auth/github-oauth.test.d.ts +2 -0
- package/dist/auth/github-oauth.test.d.ts.map +1 -0
- package/dist/auth/github-oauth.test.js +202 -0
- package/dist/auth/github-oauth.test.js.map +1 -0
- package/dist/auth/google-oauth.d.ts +3 -3
- package/dist/auth/google-oauth.d.ts.map +1 -1
- package/dist/auth/google-oauth.js +89 -26
- package/dist/auth/google-oauth.js.map +1 -1
- package/dist/auth/google-oauth.test.js +105 -35
- package/dist/auth/google-oauth.test.js.map +1 -1
- package/dist/auth/oauth.d.ts +3 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +28 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/oauth.test.d.ts +2 -0
- package/dist/auth/oauth.test.d.ts.map +1 -0
- package/dist/auth/oauth.test.js +233 -0
- package/dist/auth/oauth.test.js.map +1 -0
- package/dist/firebase-edge-errors.d.ts +95 -0
- package/dist/firebase-edge-errors.d.ts.map +1 -0
- package/dist/firebase-edge-errors.js +102 -0
- package/dist/firebase-edge-errors.js.map +1 -0
- package/dist/firebase-edge-errors.test.d.ts +2 -0
- package/dist/firebase-edge-errors.test.d.ts.map +1 -0
- package/dist/firebase-edge-errors.test.js +72 -0
- package/dist/firebase-edge-errors.test.js.map +1 -0
- package/dist/firebase-edge-server.d.ts +5 -4
- package/dist/firebase-edge-server.d.ts.map +1 -1
- package/dist/firebase-edge-server.js +22 -17
- package/dist/firebase-edge-server.js.map +1 -1
- package/dist/firebase-edge-server.test.js +55 -7
- package/dist/firebase-edge-server.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,100 +2,36 @@ import type { FirebaseCreateAuthUriResponse, FirebaseIdpSignInResponse, Firebase
|
|
|
2
2
|
import type { JsonWebKey } from 'crypto';
|
|
3
3
|
export declare function refreshFirebaseIdToken(refreshToken: string, key: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
4
4
|
data: FirebaseRefreshTokenResponse | null;
|
|
5
|
-
error:
|
|
6
|
-
code: number;
|
|
7
|
-
message: string;
|
|
8
|
-
errors?: {
|
|
9
|
-
message: string;
|
|
10
|
-
domain: string;
|
|
11
|
-
reason: string;
|
|
12
|
-
}[];
|
|
13
|
-
} | null;
|
|
5
|
+
error: import("./errors.js").FirebaseEdgeError | null;
|
|
14
6
|
}>;
|
|
15
|
-
export declare function createAuthUri(redirect_uri: string, key: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
7
|
+
export declare function createAuthUri(redirect_uri: string, key: string, tenantId?: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
16
8
|
data: FirebaseCreateAuthUriResponse | null;
|
|
17
|
-
error:
|
|
18
|
-
code: number;
|
|
19
|
-
message: string;
|
|
20
|
-
errors?: {
|
|
21
|
-
message: string;
|
|
22
|
-
domain: string;
|
|
23
|
-
reason: string;
|
|
24
|
-
}[];
|
|
25
|
-
} | null;
|
|
9
|
+
error: import("./errors.js").FirebaseEdgeError | null;
|
|
26
10
|
}>;
|
|
27
|
-
export declare function signInWithIdp(providerIdToken: string, requestUri: string, providerId: string | undefined, key: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
11
|
+
export declare function signInWithIdp(providerIdToken: string, requestUri: string, providerId: string | undefined, key: string, tenantId?: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
28
12
|
data: FirebaseIdpSignInResponse | null;
|
|
29
|
-
error:
|
|
30
|
-
code: number;
|
|
31
|
-
message: string;
|
|
32
|
-
errors?: {
|
|
33
|
-
message: string;
|
|
34
|
-
domain: string;
|
|
35
|
-
reason: string;
|
|
36
|
-
}[];
|
|
37
|
-
} | null;
|
|
13
|
+
error: import("./errors.js").FirebaseEdgeError | null;
|
|
38
14
|
}>;
|
|
39
|
-
export declare function signInWithCustomToken(jwtToken: string, key: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
15
|
+
export declare function signInWithCustomToken(jwtToken: string, key: string, tenantId?: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
40
16
|
data: FirebaseIdpSignInResponse | null;
|
|
41
|
-
error:
|
|
42
|
-
code: number;
|
|
43
|
-
message: string;
|
|
44
|
-
errors?: {
|
|
45
|
-
message: string;
|
|
46
|
-
domain: string;
|
|
47
|
-
reason: string;
|
|
48
|
-
}[];
|
|
49
|
-
} | null;
|
|
17
|
+
error: import("./errors.js").FirebaseEdgeError | null;
|
|
50
18
|
}>;
|
|
51
|
-
export declare function getAccountInfoByUid(uid: string, token: string, project_id: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
19
|
+
export declare function getAccountInfoByUid(uid: string, token: string, project_id: string, tenantId?: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
52
20
|
data: UserRecord | null | undefined;
|
|
53
|
-
error:
|
|
54
|
-
code: number;
|
|
55
|
-
message: string;
|
|
56
|
-
errors?: {
|
|
57
|
-
message: string;
|
|
58
|
-
domain: string;
|
|
59
|
-
reason: string;
|
|
60
|
-
}[];
|
|
61
|
-
} | null;
|
|
21
|
+
error: import("./errors.js").FirebaseEdgeError | null;
|
|
62
22
|
}>;
|
|
63
|
-
export declare function createSessionCookie(idToken: string, token: string, project_id: string, expiresIn?: number, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
23
|
+
export declare function createSessionCookie(idToken: string, token: string, project_id: string, expiresIn?: number, tenantId?: string, fetchFn?: typeof globalThis.fetch): Promise<{
|
|
64
24
|
data: string | null;
|
|
65
|
-
error:
|
|
66
|
-
code: number;
|
|
67
|
-
message: string;
|
|
68
|
-
errors?: {
|
|
69
|
-
message: string;
|
|
70
|
-
domain: string;
|
|
71
|
-
reason: string;
|
|
72
|
-
}[];
|
|
73
|
-
} | null;
|
|
25
|
+
error: import("./errors.js").FirebaseEdgeError | null;
|
|
74
26
|
}>;
|
|
75
27
|
export declare function getJWKs(fetchFn?: typeof globalThis.fetch): Promise<{
|
|
76
28
|
data: (JsonWebKey & {
|
|
77
29
|
kid: string;
|
|
78
30
|
})[] | null;
|
|
79
|
-
error:
|
|
80
|
-
code: number;
|
|
81
|
-
message: string;
|
|
82
|
-
errors?: {
|
|
83
|
-
message: string;
|
|
84
|
-
domain: string;
|
|
85
|
-
reason: string;
|
|
86
|
-
}[];
|
|
87
|
-
} | null;
|
|
31
|
+
error: import("./errors.js").FirebaseEdgeError | null;
|
|
88
32
|
}>;
|
|
89
33
|
export declare function getPublicKeys(fetchFn?: typeof globalThis.fetch): Promise<{
|
|
90
34
|
data: Record<string, string> | null;
|
|
91
|
-
error:
|
|
92
|
-
code: number;
|
|
93
|
-
message: string;
|
|
94
|
-
errors?: {
|
|
95
|
-
message: string;
|
|
96
|
-
domain: string;
|
|
97
|
-
reason: string;
|
|
98
|
-
}[];
|
|
99
|
-
} | null;
|
|
35
|
+
error: import("./errors.js").FirebaseEdgeError | null;
|
|
100
36
|
}>;
|
|
101
37
|
//# sourceMappingURL=firebase-auth-endpoints.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firebase-auth-endpoints.d.ts","sourceRoot":"","sources":["../../src/auth/firebase-auth-endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,6BAA6B,EAC7B,yBAAyB,EACzB,4BAA4B,EAE5B,UAAU,EACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"firebase-auth-endpoints.d.ts","sourceRoot":"","sources":["../../src/auth/firebase-auth-endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,6BAA6B,EAC7B,yBAAyB,EACzB,4BAA4B,EAE5B,UAAU,EACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAuBzC,wBAAsB,sBAAsB,CACxC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;;;GAuBpC;AAED,wBAAsB,aAAa,CAC/B,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;;;GAyBpC;AAED,wBAAsB,aAAa,CAC/B,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,EAClB,UAAU,oBAAe,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;;;GAmCpC;AAED,wBAAsB,qBAAqB,CACvC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;;;GAyBpC;AAED,wBAAsB,mBAAmB,CACrC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;;;GAsBpC;AAED,wBAAsB,mBAAmB,CACrC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAiC,EAC5C,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;;;GA4BpC;AAED,wBAAsB,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;;aAK1B,MAAM;;;GAW1C;AAED,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;;;GAgBpE"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { restFetch } from '../rest-fetch.js';
|
|
2
|
+
import { mapFirebaseError } from './auth-endpoint-errors.js';
|
|
2
3
|
// Functions
|
|
3
|
-
function createAdminIdentityURL(project_id, name, accounts = true) {
|
|
4
|
+
function createAdminIdentityURL(project_id, name, accounts = true, tenantId) {
|
|
5
|
+
if (tenantId) {
|
|
6
|
+
// Use Identity Platform API for tenant-specific operations
|
|
7
|
+
return `https://identitytoolkit.googleapis.com/v1/projects/${project_id}/tenants/${tenantId}${accounts ? '/accounts' : ''}:${name}`;
|
|
8
|
+
}
|
|
4
9
|
return `https://identitytoolkit.googleapis.com/v1/projects/${project_id}${accounts ? '/accounts' : ''}:${name}`;
|
|
5
10
|
}
|
|
6
11
|
function createIdentityURL(name) {
|
|
12
|
+
// Standard Firebase Auth REST API - tenant ID goes in request body, not URL
|
|
7
13
|
return `https://identitytoolkit.googleapis.com/v1/accounts:${name}`;
|
|
8
14
|
}
|
|
9
15
|
export async function refreshFirebaseIdToken(refreshToken, key, fetchFn) {
|
|
@@ -21,94 +27,104 @@ export async function refreshFirebaseIdToken(refreshToken, key, fetchFn) {
|
|
|
21
27
|
});
|
|
22
28
|
return {
|
|
23
29
|
data,
|
|
24
|
-
error: error ? error.error : null
|
|
30
|
+
error: error ? mapFirebaseError(error.error) : null
|
|
25
31
|
};
|
|
26
32
|
}
|
|
27
|
-
export async function createAuthUri(redirect_uri, key, fetchFn) {
|
|
33
|
+
export async function createAuthUri(redirect_uri, key, tenantId, fetchFn) {
|
|
28
34
|
const url = createIdentityURL('createAuthUri');
|
|
35
|
+
const body = {
|
|
36
|
+
continueUri: redirect_uri,
|
|
37
|
+
providerId: 'google.com',
|
|
38
|
+
...(tenantId && { tenantId })
|
|
39
|
+
};
|
|
29
40
|
const { data, error } = await restFetch(url, {
|
|
30
41
|
global: { fetch: fetchFn },
|
|
31
|
-
body
|
|
32
|
-
continueUri: redirect_uri,
|
|
33
|
-
providerId: 'google.com'
|
|
34
|
-
},
|
|
42
|
+
body,
|
|
35
43
|
params: {
|
|
36
44
|
key
|
|
37
45
|
}
|
|
38
46
|
});
|
|
39
47
|
return {
|
|
40
48
|
data,
|
|
41
|
-
error: error ? error.error : null
|
|
49
|
+
error: error ? mapFirebaseError(error.error) : null
|
|
42
50
|
};
|
|
43
51
|
}
|
|
44
|
-
export async function signInWithIdp(providerIdToken, requestUri, providerId = 'google.com', key, fetchFn) {
|
|
52
|
+
export async function signInWithIdp(providerIdToken, requestUri, providerId = 'google.com', key, tenantId, fetchFn) {
|
|
45
53
|
const url = createIdentityURL('signInWithIdp');
|
|
46
54
|
const tokenField = providerId === 'github.com' ? 'access_token' : 'id_token';
|
|
47
55
|
const postBody = new URLSearchParams({
|
|
48
56
|
[tokenField]: providerIdToken,
|
|
49
57
|
providerId
|
|
50
58
|
}).toString();
|
|
59
|
+
const body = {
|
|
60
|
+
postBody,
|
|
61
|
+
requestUri,
|
|
62
|
+
returnSecureToken: true,
|
|
63
|
+
returnIdpCredential: true,
|
|
64
|
+
...(tenantId && { tenantId })
|
|
65
|
+
};
|
|
51
66
|
const { data, error } = await restFetch(url, {
|
|
52
67
|
global: { fetch: fetchFn },
|
|
53
|
-
body
|
|
54
|
-
postBody,
|
|
55
|
-
requestUri,
|
|
56
|
-
returnSecureToken: true,
|
|
57
|
-
returnIdpCredential: true
|
|
58
|
-
},
|
|
68
|
+
body,
|
|
59
69
|
params: {
|
|
60
70
|
key
|
|
61
71
|
}
|
|
62
72
|
});
|
|
63
73
|
return {
|
|
64
74
|
data,
|
|
65
|
-
error: error ? error.error : null
|
|
75
|
+
error: error ? mapFirebaseError(error.error) : null
|
|
66
76
|
};
|
|
67
77
|
}
|
|
68
|
-
export async function signInWithCustomToken(jwtToken, key, fetchFn) {
|
|
78
|
+
export async function signInWithCustomToken(jwtToken, key, tenantId, fetchFn) {
|
|
69
79
|
const url = createIdentityURL('signInWithCustomToken');
|
|
80
|
+
const body = {
|
|
81
|
+
token: jwtToken,
|
|
82
|
+
returnSecureToken: true,
|
|
83
|
+
...(tenantId && { tenantId })
|
|
84
|
+
};
|
|
70
85
|
const { data, error } = await restFetch(url, {
|
|
71
86
|
global: { fetch: fetchFn },
|
|
72
|
-
body
|
|
73
|
-
token: jwtToken,
|
|
74
|
-
returnSecureToken: true
|
|
75
|
-
},
|
|
87
|
+
body,
|
|
76
88
|
params: {
|
|
77
89
|
key
|
|
78
90
|
}
|
|
79
91
|
});
|
|
80
92
|
return {
|
|
81
93
|
data,
|
|
82
|
-
error: error ? error.error : null
|
|
94
|
+
error: error ? mapFirebaseError(error.error) : null
|
|
83
95
|
};
|
|
84
96
|
}
|
|
85
|
-
export async function getAccountInfoByUid(uid, token, project_id, fetchFn) {
|
|
86
|
-
const url = createAdminIdentityURL(project_id, 'lookup');
|
|
97
|
+
export async function getAccountInfoByUid(uid, token, project_id, tenantId, fetchFn) {
|
|
98
|
+
const url = createAdminIdentityURL(project_id, 'lookup', true, tenantId);
|
|
99
|
+
const body = {
|
|
100
|
+
localId: uid,
|
|
101
|
+
...(tenantId && { tenantId })
|
|
102
|
+
};
|
|
87
103
|
const { data, error } = await restFetch(url, {
|
|
88
104
|
global: { fetch: fetchFn },
|
|
89
|
-
body
|
|
90
|
-
localId: uid
|
|
91
|
-
},
|
|
105
|
+
body,
|
|
92
106
|
bearerToken: token
|
|
93
107
|
});
|
|
94
108
|
return {
|
|
95
109
|
data: data?.users.length ? data.users[0] : null,
|
|
96
|
-
error: error ? error.error : null
|
|
110
|
+
error: error ? mapFirebaseError(error.error) : null
|
|
97
111
|
};
|
|
98
112
|
}
|
|
99
|
-
export async function createSessionCookie(idToken, token, project_id, expiresIn = 60 * 60 * 24 * 14 * 1000, fetchFn) {
|
|
100
|
-
const url = createAdminIdentityURL(project_id, 'createSessionCookie', false);
|
|
113
|
+
export async function createSessionCookie(idToken, token, project_id, expiresIn = 60 * 60 * 24 * 14 * 1000, tenantId, fetchFn) {
|
|
114
|
+
const url = createAdminIdentityURL(project_id, 'createSessionCookie', false, tenantId);
|
|
115
|
+
const body = {
|
|
116
|
+
idToken,
|
|
117
|
+
validDuration: Math.floor(expiresIn / 1000),
|
|
118
|
+
...(tenantId && { tenantId })
|
|
119
|
+
};
|
|
101
120
|
const { data, error } = await restFetch(url, {
|
|
102
121
|
global: { fetch: fetchFn },
|
|
103
|
-
body
|
|
104
|
-
idToken,
|
|
105
|
-
validDuration: Math.floor(expiresIn / 1000)
|
|
106
|
-
},
|
|
122
|
+
body,
|
|
107
123
|
bearerToken: token
|
|
108
124
|
});
|
|
109
125
|
return {
|
|
110
126
|
data: data?.sessionCookie || null,
|
|
111
|
-
error: error ? error.error : null
|
|
127
|
+
error: error ? mapFirebaseError(error.error) : null
|
|
112
128
|
};
|
|
113
129
|
}
|
|
114
130
|
export async function getJWKs(fetchFn) {
|
|
@@ -119,7 +135,7 @@ export async function getJWKs(fetchFn) {
|
|
|
119
135
|
});
|
|
120
136
|
return {
|
|
121
137
|
data: data?.keys || null,
|
|
122
|
-
error: error ? error.error : null
|
|
138
|
+
error: error ? mapFirebaseError(error.error) : null
|
|
123
139
|
};
|
|
124
140
|
}
|
|
125
141
|
export async function getPublicKeys(fetchFn) {
|
|
@@ -130,7 +146,7 @@ export async function getPublicKeys(fetchFn) {
|
|
|
130
146
|
});
|
|
131
147
|
return {
|
|
132
148
|
data,
|
|
133
|
-
error: error ? error.error : null
|
|
149
|
+
error: error ? mapFirebaseError(error.error) : null
|
|
134
150
|
};
|
|
135
151
|
}
|
|
136
152
|
//# sourceMappingURL=firebase-auth-endpoints.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firebase-auth-endpoints.js","sourceRoot":"","sources":["../../src/auth/firebase-auth-endpoints.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"firebase-auth-endpoints.js","sourceRoot":"","sources":["../../src/auth/firebase-auth-endpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
2
|
import { refreshFirebaseIdToken, createAuthUri, signInWithIdp, signInWithCustomToken, getAccountInfoByUid, createSessionCookie, getJWKs, getPublicKeys } from './firebase-auth-endpoints.js';
|
|
3
3
|
import * as restFetch from '../rest-fetch.js';
|
|
4
|
+
import { FirebaseEdgeError, FirebaseEndpointErrorInfo } from './errors.js';
|
|
4
5
|
vi.mock('../rest-fetch.js');
|
|
5
6
|
describe('firebase-auth-endpoints', () => {
|
|
6
7
|
const mockFetch = vi.fn();
|
|
@@ -36,14 +37,18 @@ describe('firebase-auth-endpoints', () => {
|
|
|
36
37
|
}));
|
|
37
38
|
});
|
|
38
39
|
it('should handle error response', async () => {
|
|
39
|
-
const mockError = {
|
|
40
|
+
const mockError = {
|
|
41
|
+
code: 400,
|
|
42
|
+
message: 'INVALID_GRANT: Invalid refresh token'
|
|
43
|
+
};
|
|
40
44
|
vi.mocked(restFetch.restFetch).mockResolvedValue({
|
|
41
45
|
data: null,
|
|
42
46
|
error: { error: mockError }
|
|
43
47
|
});
|
|
44
48
|
const result = await refreshFirebaseIdToken('invalid-token', API_KEY);
|
|
45
49
|
expect(result.data).toBeNull();
|
|
46
|
-
expect(result.error).
|
|
50
|
+
expect(result.error).toBeInstanceOf(FirebaseEdgeError);
|
|
51
|
+
expect(result.error.code).toBe(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_REFRESH_TOKEN.code);
|
|
47
52
|
});
|
|
48
53
|
});
|
|
49
54
|
describe('createAuthUri', () => {
|
|
@@ -55,7 +60,7 @@ describe('firebase-auth-endpoints', () => {
|
|
|
55
60
|
data: mockResponse,
|
|
56
61
|
error: null
|
|
57
62
|
});
|
|
58
|
-
const result = await createAuthUri('https://redirect.com', API_KEY, mockFetch);
|
|
63
|
+
const result = await createAuthUri('https://redirect.com', API_KEY, undefined, mockFetch);
|
|
59
64
|
expect(result.data).toEqual(mockResponse);
|
|
60
65
|
expect(restFetchSpy).toHaveBeenCalled();
|
|
61
66
|
expect(result.error).toBeNull();
|
|
@@ -68,6 +73,28 @@ describe('firebase-auth-endpoints', () => {
|
|
|
68
73
|
global: { fetch: mockFetch }
|
|
69
74
|
}));
|
|
70
75
|
});
|
|
76
|
+
it('should create auth URI with tenant ID', async () => {
|
|
77
|
+
const mockResponse = { authUri: 'https://auth.example.com' };
|
|
78
|
+
const tenantId = 'tenant-123';
|
|
79
|
+
const restFetchSpy = vi
|
|
80
|
+
.mocked(restFetch.restFetch)
|
|
81
|
+
.mockResolvedValue({
|
|
82
|
+
data: mockResponse,
|
|
83
|
+
error: null
|
|
84
|
+
});
|
|
85
|
+
const result = await createAuthUri('https://redirect.com', API_KEY, tenantId, mockFetch);
|
|
86
|
+
expect(result.data).toEqual(mockResponse);
|
|
87
|
+
expect(result.error).toBeNull();
|
|
88
|
+
expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:createAuthUri', expect.objectContaining({
|
|
89
|
+
body: {
|
|
90
|
+
continueUri: 'https://redirect.com',
|
|
91
|
+
providerId: 'google.com',
|
|
92
|
+
tenantId: tenantId
|
|
93
|
+
},
|
|
94
|
+
params: { key: API_KEY },
|
|
95
|
+
global: { fetch: mockFetch }
|
|
96
|
+
}));
|
|
97
|
+
});
|
|
71
98
|
});
|
|
72
99
|
describe('signInWithIdp', () => {
|
|
73
100
|
it('should sign in with IDP successfully', async () => {
|
|
@@ -79,7 +106,7 @@ describe('firebase-auth-endpoints', () => {
|
|
|
79
106
|
data: mockResponse,
|
|
80
107
|
error: null
|
|
81
108
|
});
|
|
82
|
-
const result = await signInWithIdp('provider-token', 'https://request.com', 'google.com', API_KEY, mockFetch);
|
|
109
|
+
const result = await signInWithIdp('provider-token', 'https://request.com', 'google.com', API_KEY, undefined, mockFetch);
|
|
83
110
|
expect(result.data).toEqual(mockResponse);
|
|
84
111
|
expect(result.error).toBeNull();
|
|
85
112
|
expect(restFetch.restFetch).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp', expect.objectContaining({
|
|
@@ -91,6 +118,50 @@ describe('firebase-auth-endpoints', () => {
|
|
|
91
118
|
}
|
|
92
119
|
}));
|
|
93
120
|
});
|
|
121
|
+
it('should sign in with IDP and tenant ID', async () => {
|
|
122
|
+
const mockResponse = {
|
|
123
|
+
idToken: 'firebase-token',
|
|
124
|
+
refreshToken: 'refresh'
|
|
125
|
+
};
|
|
126
|
+
const tenantId = 'tenant-456';
|
|
127
|
+
const restFetchSpy = vi
|
|
128
|
+
.mocked(restFetch.restFetch)
|
|
129
|
+
.mockResolvedValue({
|
|
130
|
+
data: mockResponse,
|
|
131
|
+
error: null
|
|
132
|
+
});
|
|
133
|
+
const result = await signInWithIdp('provider-token', 'https://request.com', 'google.com', API_KEY, tenantId, mockFetch);
|
|
134
|
+
expect(result.data).toEqual(mockResponse);
|
|
135
|
+
expect(result.error).toBeNull();
|
|
136
|
+
expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp', expect.objectContaining({
|
|
137
|
+
body: {
|
|
138
|
+
postBody: 'id_token=provider-token&providerId=google.com',
|
|
139
|
+
requestUri: 'https://request.com',
|
|
140
|
+
returnSecureToken: true,
|
|
141
|
+
returnIdpCredential: true,
|
|
142
|
+
tenantId: tenantId
|
|
143
|
+
}
|
|
144
|
+
}));
|
|
145
|
+
});
|
|
146
|
+
it('should use access_token for GitHub provider', async () => {
|
|
147
|
+
const mockResponse = {
|
|
148
|
+
idToken: 'firebase-token',
|
|
149
|
+
refreshToken: 'refresh'
|
|
150
|
+
};
|
|
151
|
+
const restFetchSpy = vi
|
|
152
|
+
.mocked(restFetch.restFetch)
|
|
153
|
+
.mockResolvedValue({
|
|
154
|
+
data: mockResponse,
|
|
155
|
+
error: null
|
|
156
|
+
});
|
|
157
|
+
const result = await signInWithIdp('github-token', 'https://request.com', 'github.com', API_KEY, undefined, mockFetch);
|
|
158
|
+
expect(result.data).toEqual(mockResponse);
|
|
159
|
+
expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp', expect.objectContaining({
|
|
160
|
+
body: expect.objectContaining({
|
|
161
|
+
postBody: 'access_token=github-token&providerId=github.com'
|
|
162
|
+
})
|
|
163
|
+
}));
|
|
164
|
+
});
|
|
94
165
|
});
|
|
95
166
|
describe('signInWithCustomToken', () => {
|
|
96
167
|
it('should sign in with custom token successfully', async () => {
|
|
@@ -99,10 +170,30 @@ describe('firebase-auth-endpoints', () => {
|
|
|
99
170
|
data: mockResponse,
|
|
100
171
|
error: null
|
|
101
172
|
});
|
|
102
|
-
const result = await signInWithCustomToken('jwt-token', API_KEY, mockFetch);
|
|
173
|
+
const result = await signInWithCustomToken('jwt-token', API_KEY, undefined, mockFetch);
|
|
103
174
|
expect(result.data).toEqual(mockResponse);
|
|
104
175
|
expect(result.error).toBeNull();
|
|
105
176
|
});
|
|
177
|
+
it('should sign in with custom token and tenant ID', async () => {
|
|
178
|
+
const mockResponse = { idToken: 'firebase-token' };
|
|
179
|
+
const tenantId = 'tenant-789';
|
|
180
|
+
const restFetchSpy = vi
|
|
181
|
+
.mocked(restFetch.restFetch)
|
|
182
|
+
.mockResolvedValue({
|
|
183
|
+
data: mockResponse,
|
|
184
|
+
error: null
|
|
185
|
+
});
|
|
186
|
+
const result = await signInWithCustomToken('jwt-token', API_KEY, tenantId, mockFetch);
|
|
187
|
+
expect(result.data).toEqual(mockResponse);
|
|
188
|
+
expect(result.error).toBeNull();
|
|
189
|
+
expect(restFetchSpy).toHaveBeenCalledWith('https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken', expect.objectContaining({
|
|
190
|
+
body: {
|
|
191
|
+
token: 'jwt-token',
|
|
192
|
+
returnSecureToken: true,
|
|
193
|
+
tenantId: tenantId
|
|
194
|
+
}
|
|
195
|
+
}));
|
|
196
|
+
});
|
|
106
197
|
});
|
|
107
198
|
describe('getAccountInfoByUid', () => {
|
|
108
199
|
it('should get account info successfully', async () => {
|
|
@@ -111,9 +202,29 @@ describe('firebase-auth-endpoints', () => {
|
|
|
111
202
|
data: { users: [mockUser] },
|
|
112
203
|
error: null
|
|
113
204
|
});
|
|
114
|
-
const result = await getAccountInfoByUid('user-123', ACCESS_TOKEN, PROJECT_ID, mockFetch);
|
|
205
|
+
const result = await getAccountInfoByUid('user-123', ACCESS_TOKEN, PROJECT_ID, undefined, mockFetch);
|
|
206
|
+
expect(result.data).toEqual(mockUser);
|
|
207
|
+
expect(result.error).toBeNull();
|
|
208
|
+
});
|
|
209
|
+
it('should get account info with tenant ID', async () => {
|
|
210
|
+
const mockUser = { localId: 'user-123', email: 'test@example.com' };
|
|
211
|
+
const tenantId = 'tenant-abc';
|
|
212
|
+
const restFetchSpy = vi
|
|
213
|
+
.mocked(restFetch.restFetch)
|
|
214
|
+
.mockResolvedValue({
|
|
215
|
+
data: { users: [mockUser] },
|
|
216
|
+
error: null
|
|
217
|
+
});
|
|
218
|
+
const result = await getAccountInfoByUid('user-123', ACCESS_TOKEN, PROJECT_ID, tenantId, mockFetch);
|
|
115
219
|
expect(result.data).toEqual(mockUser);
|
|
116
220
|
expect(result.error).toBeNull();
|
|
221
|
+
expect(restFetchSpy).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/${PROJECT_ID}/tenants/${tenantId}/accounts:lookup`, expect.objectContaining({
|
|
222
|
+
body: {
|
|
223
|
+
localId: 'user-123',
|
|
224
|
+
tenantId: tenantId
|
|
225
|
+
},
|
|
226
|
+
bearerToken: ACCESS_TOKEN
|
|
227
|
+
}));
|
|
117
228
|
});
|
|
118
229
|
it('should return null when no users found', async () => {
|
|
119
230
|
vi.mocked(restFetch.restFetch).mockResolvedValue({
|
|
@@ -133,7 +244,7 @@ describe('firebase-auth-endpoints', () => {
|
|
|
133
244
|
data: mockResponse,
|
|
134
245
|
error: null
|
|
135
246
|
});
|
|
136
|
-
const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, undefined, mockFetch);
|
|
247
|
+
const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, undefined, undefined, mockFetch);
|
|
137
248
|
expect(result.data).toBe('cookie-value');
|
|
138
249
|
expect(restFetchSpy).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/${PROJECT_ID}:createSessionCookie`, expect.objectContaining({
|
|
139
250
|
body: expect.objectContaining({
|
|
@@ -142,6 +253,27 @@ describe('firebase-auth-endpoints', () => {
|
|
|
142
253
|
})
|
|
143
254
|
}));
|
|
144
255
|
});
|
|
256
|
+
it('should create session cookie with tenant ID', async () => {
|
|
257
|
+
const mockResponse = { sessionCookie: 'cookie-value' };
|
|
258
|
+
const tenantId = 'tenant-def';
|
|
259
|
+
const restFetchSpy = vi
|
|
260
|
+
.mocked(restFetch.restFetch)
|
|
261
|
+
.mockResolvedValue({
|
|
262
|
+
data: mockResponse,
|
|
263
|
+
error: null
|
|
264
|
+
});
|
|
265
|
+
const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, 3600000, // 1 hour in ms
|
|
266
|
+
tenantId, mockFetch);
|
|
267
|
+
expect(result.data).toBe('cookie-value');
|
|
268
|
+
expect(restFetchSpy).toHaveBeenCalledWith(`https://identitytoolkit.googleapis.com/v1/projects/${PROJECT_ID}/tenants/${tenantId}:createSessionCookie`, expect.objectContaining({
|
|
269
|
+
body: {
|
|
270
|
+
idToken: 'id-token',
|
|
271
|
+
validDuration: 3600, // converted to seconds
|
|
272
|
+
tenantId: tenantId
|
|
273
|
+
},
|
|
274
|
+
bearerToken: ACCESS_TOKEN
|
|
275
|
+
}));
|
|
276
|
+
});
|
|
145
277
|
it('should create session cookie with custom expiry (using seconds)', async () => {
|
|
146
278
|
const mockResponse = { sessionCookie: 'cookie-value' };
|
|
147
279
|
vi.mocked(restFetch.restFetch).mockResolvedValue({
|
|
@@ -149,7 +281,7 @@ describe('firebase-auth-endpoints', () => {
|
|
|
149
281
|
error: null
|
|
150
282
|
});
|
|
151
283
|
const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, 3600, // 1 hour in seconds
|
|
152
|
-
mockFetch);
|
|
284
|
+
undefined, mockFetch);
|
|
153
285
|
expect(result.data).toBe('cookie-value');
|
|
154
286
|
});
|
|
155
287
|
});
|
|
@@ -185,17 +317,21 @@ describe('firebase-auth-endpoints', () => {
|
|
|
185
317
|
expect(result.error).toBeNull();
|
|
186
318
|
});
|
|
187
319
|
it('should handle error response', async () => {
|
|
188
|
-
const mockError = {
|
|
320
|
+
const mockError = {
|
|
321
|
+
code: 403,
|
|
322
|
+
message: 'PERMISSION_DENIED: Failed to fetch keys'
|
|
323
|
+
};
|
|
189
324
|
vi.mocked(restFetch.restFetch).mockResolvedValue({
|
|
190
325
|
data: null,
|
|
191
326
|
error: { error: mockError }
|
|
192
327
|
});
|
|
193
328
|
const result = await getPublicKeys();
|
|
194
329
|
expect(result.data).toBeNull();
|
|
195
|
-
expect(result.error).
|
|
330
|
+
expect(result.error).toBeInstanceOf(FirebaseEdgeError);
|
|
331
|
+
expect(result.error.code).toBe(FirebaseEndpointErrorInfo.ENDPOINT_PERMISSION_DENIED.code);
|
|
196
332
|
});
|
|
197
333
|
});
|
|
198
|
-
describe('createAdminIdentityURL (indirectly via
|
|
334
|
+
describe('createAdminIdentityURL (indirectly via functions)', () => {
|
|
199
335
|
it('should call createSessionCookie URL without /accounts segment', async () => {
|
|
200
336
|
const mockResponse = { sessionCookie: 'cookie-value' };
|
|
201
337
|
const restFetchSpy = vi
|
|
@@ -207,7 +343,7 @@ describe('firebase-auth-endpoints', () => {
|
|
|
207
343
|
const idToken = 'id-token';
|
|
208
344
|
const token = 'access-token';
|
|
209
345
|
const projectId = 'test-project';
|
|
210
|
-
const result = await createSessionCookie(idToken, token, projectId, 3600_000, vi.fn());
|
|
346
|
+
const result = await createSessionCookie(idToken, token, projectId, 3600_000, undefined, vi.fn());
|
|
211
347
|
expect(result.data).toBe('cookie-value');
|
|
212
348
|
expect(restFetchSpy).toHaveBeenCalledTimes(1);
|
|
213
349
|
const [calledUrl, options] = restFetchSpy.mock
|
|
@@ -216,6 +352,20 @@ describe('firebase-auth-endpoints', () => {
|
|
|
216
352
|
expect(options.bearerToken).toBe(token);
|
|
217
353
|
expect(options.body.idToken).toBe(idToken);
|
|
218
354
|
});
|
|
355
|
+
it('should call createSessionCookie tenant URL when tenant ID provided', async () => {
|
|
356
|
+
const mockResponse = { sessionCookie: 'cookie-value' };
|
|
357
|
+
const tenantId = 'tenant-test';
|
|
358
|
+
const restFetchSpy = vi
|
|
359
|
+
.mocked(restFetch.restFetch)
|
|
360
|
+
.mockResolvedValue({
|
|
361
|
+
data: mockResponse,
|
|
362
|
+
error: null
|
|
363
|
+
});
|
|
364
|
+
const result = await createSessionCookie('id-token', 'access-token', 'test-project', 3600_000, tenantId, vi.fn());
|
|
365
|
+
expect(result.data).toBe('cookie-value');
|
|
366
|
+
const [calledUrl] = restFetchSpy.mock.calls[0];
|
|
367
|
+
expect(calledUrl).toBe(`https://identitytoolkit.googleapis.com/v1/projects/test-project/tenants/${tenantId}:createSessionCookie`);
|
|
368
|
+
});
|
|
219
369
|
it('should call accounts lookup URL with /accounts segment via getAccountInfoByUid', async () => {
|
|
220
370
|
const mockUser = { localId: 'user-123', email: 'test@example.com' };
|
|
221
371
|
const restFetchSpy = vi
|
|
@@ -227,7 +377,7 @@ describe('firebase-auth-endpoints', () => {
|
|
|
227
377
|
const uid = 'user-123';
|
|
228
378
|
const token = 'access-token';
|
|
229
379
|
const projectId = 'test-project';
|
|
230
|
-
const result = await getAccountInfoByUid(uid, token, projectId, vi.fn());
|
|
380
|
+
const result = await getAccountInfoByUid(uid, token, projectId, undefined, vi.fn());
|
|
231
381
|
expect(result.data).toEqual(mockUser);
|
|
232
382
|
expect(restFetchSpy).toHaveBeenCalledTimes(1);
|
|
233
383
|
const [calledUrl, options] = restFetchSpy.mock
|
|
@@ -236,6 +386,20 @@ describe('firebase-auth-endpoints', () => {
|
|
|
236
386
|
expect(options.bearerToken).toBe(token);
|
|
237
387
|
expect(options.body.localId).toBe(uid);
|
|
238
388
|
});
|
|
389
|
+
it('should call accounts lookup tenant URL when tenant ID provided', async () => {
|
|
390
|
+
const mockUser = { localId: 'user-123', email: 'test@example.com' };
|
|
391
|
+
const tenantId = 'tenant-lookup';
|
|
392
|
+
const restFetchSpy = vi
|
|
393
|
+
.mocked(restFetch.restFetch)
|
|
394
|
+
.mockResolvedValue({
|
|
395
|
+
data: { users: [mockUser] },
|
|
396
|
+
error: null
|
|
397
|
+
});
|
|
398
|
+
const result = await getAccountInfoByUid('user-123', 'access-token', 'test-project', tenantId, vi.fn());
|
|
399
|
+
expect(result.data).toEqual(mockUser);
|
|
400
|
+
const [calledUrl] = restFetchSpy.mock.calls[0];
|
|
401
|
+
expect(calledUrl).toBe(`https://identitytoolkit.googleapis.com/v1/projects/test-project/tenants/${tenantId}/accounts:lookup`);
|
|
402
|
+
});
|
|
239
403
|
});
|
|
240
404
|
describe('createSessionCookie with ms input', () => {
|
|
241
405
|
it('should convert ms to seconds when creating session cookie', async () => {
|
|
@@ -247,6 +411,7 @@ describe('firebase-auth-endpoints', () => {
|
|
|
247
411
|
error: null
|
|
248
412
|
});
|
|
249
413
|
const result = await createSessionCookie('id-token', ACCESS_TOKEN, PROJECT_ID, 1209600000, // 14 days in ms
|
|
414
|
+
undefined, // tenantId
|
|
250
415
|
mockFetch);
|
|
251
416
|
expect(result.data).toBe('cookie-value');
|
|
252
417
|
expect(restFetchSpy).toHaveBeenCalledWith(expect.stringContaining('createSessionCookie'), expect.objectContaining({
|