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.
Files changed (74) hide show
  1. package/README.md +26 -0
  2. package/dist/auth/auth-endpoint-errors.d.ts +15 -0
  3. package/dist/auth/auth-endpoint-errors.d.ts.map +1 -0
  4. package/dist/auth/auth-endpoint-errors.js +120 -0
  5. package/dist/auth/auth-endpoint-errors.js.map +1 -0
  6. package/dist/auth/auth-error-codes.d.ts +777 -0
  7. package/dist/auth/auth-error-codes.d.ts.map +1 -0
  8. package/dist/auth/auth-error-codes.js +823 -0
  9. package/dist/auth/auth-error-codes.js.map +1 -0
  10. package/dist/auth/errors.d.ts +20 -0
  11. package/dist/auth/errors.d.ts.map +1 -0
  12. package/dist/auth/errors.js +29 -0
  13. package/dist/auth/errors.js.map +1 -0
  14. package/dist/auth/firebase-admin-auth.d.ts +12 -21
  15. package/dist/auth/firebase-admin-auth.d.ts.map +1 -1
  16. package/dist/auth/firebase-admin-auth.js +54 -16
  17. package/dist/auth/firebase-admin-auth.js.map +1 -1
  18. package/dist/auth/firebase-admin-auth.test.js +36 -24
  19. package/dist/auth/firebase-admin-auth.test.js.map +1 -1
  20. package/dist/auth/firebase-auth-endpoints.d.ts +13 -77
  21. package/dist/auth/firebase-auth-endpoints.d.ts.map +1 -1
  22. package/dist/auth/firebase-auth-endpoints.js +53 -37
  23. package/dist/auth/firebase-auth-endpoints.js.map +1 -1
  24. package/dist/auth/firebase-auth-endpoints.test.js +178 -13
  25. package/dist/auth/firebase-auth-endpoints.test.js.map +1 -1
  26. package/dist/auth/firebase-auth.d.ts +5 -9
  27. package/dist/auth/firebase-auth.d.ts.map +1 -1
  28. package/dist/auth/firebase-auth.js +61 -21
  29. package/dist/auth/firebase-auth.js.map +1 -1
  30. package/dist/auth/firebase-auth.test.js +29 -12
  31. package/dist/auth/firebase-auth.test.js.map +1 -1
  32. package/dist/auth/firebase-jwt.d.ts +5 -29
  33. package/dist/auth/firebase-jwt.d.ts.map +1 -1
  34. package/dist/auth/firebase-jwt.js +74 -33
  35. package/dist/auth/firebase-jwt.js.map +1 -1
  36. package/dist/auth/firebase-jwt.test.js +31 -11
  37. package/dist/auth/firebase-jwt.test.js.map +1 -1
  38. package/dist/auth/github-oauth.d.ts +5 -2
  39. package/dist/auth/github-oauth.d.ts.map +1 -1
  40. package/dist/auth/github-oauth.js +126 -13
  41. package/dist/auth/github-oauth.js.map +1 -1
  42. package/dist/auth/github-oauth.test.d.ts +2 -0
  43. package/dist/auth/github-oauth.test.d.ts.map +1 -0
  44. package/dist/auth/github-oauth.test.js +202 -0
  45. package/dist/auth/github-oauth.test.js.map +1 -0
  46. package/dist/auth/google-oauth.d.ts +3 -3
  47. package/dist/auth/google-oauth.d.ts.map +1 -1
  48. package/dist/auth/google-oauth.js +89 -26
  49. package/dist/auth/google-oauth.js.map +1 -1
  50. package/dist/auth/google-oauth.test.js +105 -35
  51. package/dist/auth/google-oauth.test.js.map +1 -1
  52. package/dist/auth/oauth.d.ts +3 -0
  53. package/dist/auth/oauth.d.ts.map +1 -0
  54. package/dist/auth/oauth.js +28 -0
  55. package/dist/auth/oauth.js.map +1 -0
  56. package/dist/auth/oauth.test.d.ts +2 -0
  57. package/dist/auth/oauth.test.d.ts.map +1 -0
  58. package/dist/auth/oauth.test.js +233 -0
  59. package/dist/auth/oauth.test.js.map +1 -0
  60. package/dist/firebase-edge-errors.d.ts +95 -0
  61. package/dist/firebase-edge-errors.d.ts.map +1 -0
  62. package/dist/firebase-edge-errors.js +102 -0
  63. package/dist/firebase-edge-errors.js.map +1 -0
  64. package/dist/firebase-edge-errors.test.d.ts +2 -0
  65. package/dist/firebase-edge-errors.test.d.ts.map +1 -0
  66. package/dist/firebase-edge-errors.test.js +72 -0
  67. package/dist/firebase-edge-errors.test.js.map +1 -0
  68. package/dist/firebase-edge-server.d.ts +5 -4
  69. package/dist/firebase-edge-server.d.ts.map +1 -1
  70. package/dist/firebase-edge-server.js +22 -17
  71. package/dist/firebase-edge-server.js.map +1 -1
  72. package/dist/firebase-edge-server.test.js +55 -7
  73. package/dist/firebase-edge-server.test.js.map +1 -1
  74. package/package.json +1 -1
package/README.md CHANGED
@@ -109,3 +109,29 @@ redirect(302, '/');
109
109
  - ✅ **Session Management** - Secure HTTP-only cookies
110
110
  - ✅ **Google OAuth** - Complete OAuth 2.0 flow
111
111
  - ✅ **Token Management** - Generate client tokens from server sessions
112
+
113
+ ## Currently Working On - (in no particular order)
114
+
115
+ - ☐ LinkProvider (auto link?)
116
+ - ☐ Unlink Provider
117
+ - ☐ App Check
118
+ - ☐ Magic Link (auto save email?)
119
+ - ☐ Email / Password
120
+ - ☐ Custom oAuth Scopes
121
+ - ☐ Get User
122
+ - ☐ Update User
123
+ - ☐ Delete User
124
+ - ☐ Add / Remove Claims
125
+ - ☐ Get all Users / Pagination
126
+ - ☐ All Providers
127
+ - ☐ Ban Users
128
+ - ☐ RBAC
129
+
130
+ ### Other TODO Notes
131
+
132
+ - Cookie Name, Cookie Options, Callback Path, Debug
133
+ - (enableTokenRefreshOnExpiredKidHeader ? cookieSignatureKeys ?)
134
+ - loginWIthCodeFromURL(url)
135
+ - next path?
136
+
137
+ ## Then to DB, then Storage...
@@ -0,0 +1,15 @@
1
+ import type { FirebaseRestError } from './firebase-types.js';
2
+ import { FirebaseEdgeError } from './errors.js';
3
+ /**
4
+ * Maps Firebase REST API errors to structured FirebaseEdgeError instances.
5
+ * This function analyzes the Firebase error codes and HTTP status codes to determine
6
+ * the most appropriate structured error type.
7
+ *
8
+ * Firebase errors come with specific error codes in the message field (e.g., USER_NOT_FOUND)
9
+ * and additional details in the errors array with reason codes.
10
+ *
11
+ * @param firebaseError - The error object from Firebase REST API
12
+ * @returns A structured FirebaseEdgeError instance
13
+ */
14
+ export declare function mapFirebaseError(firebaseError: FirebaseRestError['error']): FirebaseEdgeError;
15
+ //# sourceMappingURL=auth-endpoint-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-endpoint-errors.d.ts","sourceRoot":"","sources":["../../src/auth/auth-endpoint-errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAA6B,MAAM,aAAa,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC5B,aAAa,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAC1C,iBAAiB,CAuLnB"}
@@ -0,0 +1,120 @@
1
+ import { FirebaseEdgeError, FirebaseEndpointErrorInfo } from './errors.js';
2
+ /**
3
+ * Maps Firebase REST API errors to structured FirebaseEdgeError instances.
4
+ * This function analyzes the Firebase error codes and HTTP status codes to determine
5
+ * the most appropriate structured error type.
6
+ *
7
+ * Firebase errors come with specific error codes in the message field (e.g., USER_NOT_FOUND)
8
+ * and additional details in the errors array with reason codes.
9
+ *
10
+ * @param firebaseError - The error object from Firebase REST API
11
+ * @returns A structured FirebaseEdgeError instance
12
+ */
13
+ export function mapFirebaseError(firebaseError) {
14
+ const { code, message, errors } = firebaseError;
15
+ // First, check for specific Firebase error codes in the message field
16
+ const firebaseErrorCode = message?.toUpperCase?.() || '';
17
+ const reasonCode = errors?.[0]?.reason?.toUpperCase?.() || '';
18
+ // Map specific Firebase error codes to structured errors (check if message contains the error code)
19
+ if (firebaseErrorCode.includes('INVALID_CUSTOM_TOKEN')) {
20
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_CUSTOM_TOKEN);
21
+ }
22
+ if (firebaseErrorCode.includes('INVALID_REFRESH_TOKEN') ||
23
+ firebaseErrorCode.includes('INVALID_GRANT')) {
24
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_REFRESH_TOKEN);
25
+ }
26
+ if (firebaseErrorCode.includes('TOKEN_EXPIRED') ||
27
+ firebaseErrorCode.includes('CREDENTIAL_TOO_OLD_LOGIN_AGAIN')) {
28
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_TOKEN_EXPIRED);
29
+ }
30
+ if (firebaseErrorCode.includes('INVALID_ID_TOKEN')) {
31
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_ID_TOKEN);
32
+ }
33
+ if (firebaseErrorCode.includes('INVALID_CREDENTIAL')) {
34
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_CREDENTIAL);
35
+ }
36
+ // User Management Errors
37
+ if (firebaseErrorCode.includes('USER_NOT_FOUND') ||
38
+ firebaseErrorCode.includes('EMAIL_NOT_FOUND')) {
39
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_USER_NOT_FOUND);
40
+ }
41
+ if (firebaseErrorCode.includes('USER_DISABLED')) {
42
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_USER_DISABLED);
43
+ }
44
+ // Permission & Access Errors
45
+ if (firebaseErrorCode.includes('PERMISSION_DENIED')) {
46
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_PERMISSION_DENIED);
47
+ }
48
+ if (firebaseErrorCode.includes('INSUFFICIENT_PERMISSION')) {
49
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INSUFFICIENT_PERMISSION);
50
+ }
51
+ // Rate Limiting & Quota Errors
52
+ if (firebaseErrorCode.includes('TOO_MANY_ATTEMPTS_TRY_LATER')) {
53
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_TOO_MANY_REQUESTS);
54
+ }
55
+ if (firebaseErrorCode.includes('QUOTA_EXCEEDED')) {
56
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_QUOTA_EXCEEDED);
57
+ }
58
+ // Provider & Configuration Errors
59
+ if (firebaseErrorCode.includes('OPERATION_NOT_ALLOWED')) {
60
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_PROVIDER_NOT_ENABLED);
61
+ }
62
+ if (firebaseErrorCode.includes('INVALID_IDP_RESPONSE')) {
63
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_PROVIDER_ID);
64
+ }
65
+ // Project & API Key Errors
66
+ if (firebaseErrorCode.includes('API KEY NOT VALID') ||
67
+ firebaseErrorCode.includes('INVALID_API_KEY')) {
68
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_API_KEY);
69
+ }
70
+ // Validation Errors
71
+ if (firebaseErrorCode.includes('INVALID_EMAIL') ||
72
+ firebaseErrorCode.includes('WEAK_PASSWORD') ||
73
+ firebaseErrorCode.includes('EMAIL_EXISTS') ||
74
+ firebaseErrorCode.includes('INVALID_PASSWORD') ||
75
+ firebaseErrorCode.includes('MISSING_REFRESH_TOKEN') ||
76
+ firebaseErrorCode.includes('INVALID_GRANT_TYPE')) {
77
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_ARGUMENT);
78
+ }
79
+ // Check reason codes if main message didn't match
80
+ if (reasonCode.includes('INVALID')) {
81
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_ARGUMENT);
82
+ }
83
+ if (reasonCode.includes('FORBIDDEN')) {
84
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_FORBIDDEN);
85
+ }
86
+ if (reasonCode.includes('NOTFOUND') || reasonCode.includes('NOT_FOUND')) {
87
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_USER_NOT_FOUND);
88
+ }
89
+ // Fallback to HTTP status code mapping if no specific Firebase error code matched
90
+ switch (code) {
91
+ case 400:
92
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INVALID_ARGUMENT);
93
+ case 401:
94
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_UNAUTHORIZED);
95
+ case 403:
96
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_FORBIDDEN);
97
+ case 404:
98
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_USER_NOT_FOUND);
99
+ case 429:
100
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_TOO_MANY_REQUESTS);
101
+ case 500:
102
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_INTERNAL_ERROR);
103
+ case 502:
104
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_BAD_GATEWAY);
105
+ case 503:
106
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_SERVICE_UNAVAILABLE);
107
+ case 504:
108
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_TIMEOUT);
109
+ default:
110
+ return new FirebaseEdgeError(FirebaseEndpointErrorInfo.ENDPOINT_UNKNOWN_ERROR, {
111
+ cause: new Error(message),
112
+ context: {
113
+ firebaseCode: code,
114
+ firebaseMessage: message,
115
+ firebaseErrors: errors
116
+ }
117
+ });
118
+ }
119
+ }
120
+ //# sourceMappingURL=auth-endpoint-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-endpoint-errors.js","sourceRoot":"","sources":["../../src/auth/auth-endpoint-errors.ts"],"names":[],"mappings":"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"}