firebase-admin 12.7.0 → 13.0.0

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 (219) hide show
  1. package/README.md +1 -2
  2. package/lib/app/core.d.ts +1 -2
  3. package/lib/app/core.js +1 -1
  4. package/lib/app/credential-factory.d.ts +1 -2
  5. package/lib/app/credential-factory.js +5 -6
  6. package/lib/app/credential-internal.d.ts +37 -35
  7. package/lib/app/credential-internal.js +194 -294
  8. package/lib/app/credential.d.ts +1 -1
  9. package/lib/app/credential.js +1 -1
  10. package/lib/app/firebase-app.d.ts +1 -1
  11. package/lib/app/firebase-app.js +1 -1
  12. package/lib/app/firebase-namespace.d.ts +1 -1
  13. package/lib/app/firebase-namespace.js +1 -1
  14. package/lib/app/index.d.ts +1 -1
  15. package/lib/app/index.js +1 -1
  16. package/lib/app/lifecycle.d.ts +1 -1
  17. package/lib/app/lifecycle.js +6 -6
  18. package/lib/app-check/app-check-api-client-internal.d.ts +1 -1
  19. package/lib/app-check/app-check-api-client-internal.js +1 -1
  20. package/lib/app-check/app-check-api.d.ts +1 -1
  21. package/lib/app-check/app-check-api.js +1 -1
  22. package/lib/app-check/app-check-namespace.d.ts +1 -1
  23. package/lib/app-check/app-check-namespace.js +1 -1
  24. package/lib/app-check/app-check.d.ts +1 -1
  25. package/lib/app-check/app-check.js +1 -1
  26. package/lib/app-check/index.d.ts +1 -1
  27. package/lib/app-check/index.js +3 -3
  28. package/lib/app-check/token-generator.d.ts +1 -1
  29. package/lib/app-check/token-generator.js +3 -3
  30. package/lib/app-check/token-verifier.d.ts +1 -1
  31. package/lib/app-check/token-verifier.js +1 -1
  32. package/lib/auth/action-code-settings-builder.d.ts +1 -1
  33. package/lib/auth/action-code-settings-builder.js +1 -1
  34. package/lib/auth/auth-api-request.d.ts +1 -1
  35. package/lib/auth/auth-api-request.js +3 -4
  36. package/lib/auth/auth-config.d.ts +1 -1
  37. package/lib/auth/auth-config.js +3 -3
  38. package/lib/auth/auth-namespace.d.ts +1 -1
  39. package/lib/auth/auth-namespace.js +1 -1
  40. package/lib/auth/auth.d.ts +1 -1
  41. package/lib/auth/auth.js +1 -1
  42. package/lib/auth/base-auth.d.ts +1 -1
  43. package/lib/auth/base-auth.js +3 -3
  44. package/lib/auth/identifier.d.ts +1 -1
  45. package/lib/auth/identifier.js +5 -6
  46. package/lib/auth/index.d.ts +1 -1
  47. package/lib/auth/index.js +3 -3
  48. package/lib/auth/project-config-manager.d.ts +1 -1
  49. package/lib/auth/project-config-manager.js +1 -1
  50. package/lib/auth/project-config.d.ts +1 -1
  51. package/lib/auth/project-config.js +1 -1
  52. package/lib/auth/tenant-manager.d.ts +1 -1
  53. package/lib/auth/tenant-manager.js +1 -1
  54. package/lib/auth/tenant.d.ts +1 -1
  55. package/lib/auth/tenant.js +1 -1
  56. package/lib/auth/token-generator.d.ts +1 -2
  57. package/lib/auth/token-generator.js +3 -3
  58. package/lib/auth/token-verifier.d.ts +1 -1
  59. package/lib/auth/token-verifier.js +5 -5
  60. package/lib/auth/user-import-builder.d.ts +1 -2
  61. package/lib/auth/user-import-builder.js +3 -3
  62. package/lib/auth/user-record.d.ts +1 -1
  63. package/lib/auth/user-record.js +1 -1
  64. package/lib/credential/index.d.ts +1 -1
  65. package/lib/credential/index.js +1 -1
  66. package/lib/data-connect/data-connect-api-client-internal.d.ts +1 -1
  67. package/lib/data-connect/data-connect-api-client-internal.js +1 -1
  68. package/lib/data-connect/data-connect-api.d.ts +1 -1
  69. package/lib/data-connect/data-connect-api.js +1 -1
  70. package/lib/data-connect/data-connect.d.ts +1 -1
  71. package/lib/data-connect/data-connect.js +1 -1
  72. package/lib/data-connect/index.d.ts +1 -1
  73. package/lib/data-connect/index.js +3 -3
  74. package/lib/database/database-namespace.d.ts +1 -1
  75. package/lib/database/database-namespace.js +1 -1
  76. package/lib/database/database.d.ts +1 -2
  77. package/lib/database/database.js +1 -1
  78. package/lib/database/index.d.ts +1 -1
  79. package/lib/database/index.js +4 -4
  80. package/lib/default-namespace.d.ts +1 -1
  81. package/lib/default-namespace.js +1 -1
  82. package/lib/eventarc/cloudevent.d.ts +1 -1
  83. package/lib/eventarc/cloudevent.js +1 -1
  84. package/lib/eventarc/eventarc-client-internal.d.ts +1 -1
  85. package/lib/eventarc/eventarc-client-internal.js +1 -1
  86. package/lib/eventarc/eventarc-utils.d.ts +1 -1
  87. package/lib/eventarc/eventarc-utils.js +3 -3
  88. package/lib/eventarc/eventarc.d.ts +1 -1
  89. package/lib/eventarc/eventarc.js +1 -1
  90. package/lib/eventarc/index.d.ts +1 -1
  91. package/lib/eventarc/index.js +3 -3
  92. package/lib/extensions/extensions-api-client-internal.d.ts +1 -1
  93. package/lib/extensions/extensions-api-client-internal.js +1 -1
  94. package/lib/extensions/extensions-api.d.ts +1 -1
  95. package/lib/extensions/extensions-api.js +1 -1
  96. package/lib/extensions/extensions.d.ts +1 -1
  97. package/lib/extensions/extensions.js +1 -1
  98. package/lib/extensions/index.d.ts +1 -1
  99. package/lib/extensions/index.js +3 -3
  100. package/lib/firebase-namespace-api.d.ts +1 -1
  101. package/lib/firebase-namespace-api.js +1 -1
  102. package/lib/firestore/firestore-internal.d.ts +1 -1
  103. package/lib/firestore/firestore-internal.js +3 -3
  104. package/lib/firestore/firestore-namespace.d.ts +1 -1
  105. package/lib/firestore/firestore-namespace.js +1 -1
  106. package/lib/firestore/index.d.ts +1 -1
  107. package/lib/firestore/index.js +4 -4
  108. package/lib/functions/functions-api-client-internal.d.ts +1 -1
  109. package/lib/functions/functions-api-client-internal.js +3 -2
  110. package/lib/functions/functions-api.d.ts +1 -1
  111. package/lib/functions/functions-api.js +1 -1
  112. package/lib/functions/functions.d.ts +1 -1
  113. package/lib/functions/functions.js +1 -1
  114. package/lib/functions/index.d.ts +1 -1
  115. package/lib/functions/index.js +3 -3
  116. package/lib/index.d.ts +1 -1
  117. package/lib/index.js +1 -1
  118. package/lib/installations/index.d.ts +1 -1
  119. package/lib/installations/index.js +3 -3
  120. package/lib/installations/installations-namespace.d.ts +1 -1
  121. package/lib/installations/installations-namespace.js +1 -1
  122. package/lib/installations/installations-request-handler.d.ts +1 -1
  123. package/lib/installations/installations-request-handler.js +1 -1
  124. package/lib/installations/installations.d.ts +1 -1
  125. package/lib/installations/installations.js +1 -1
  126. package/lib/instance-id/index.d.ts +1 -1
  127. package/lib/instance-id/index.js +3 -3
  128. package/lib/instance-id/instance-id-namespace.d.ts +1 -1
  129. package/lib/instance-id/instance-id-namespace.js +1 -1
  130. package/lib/instance-id/instance-id.d.ts +1 -1
  131. package/lib/instance-id/instance-id.js +1 -1
  132. package/lib/machine-learning/index.d.ts +1 -1
  133. package/lib/machine-learning/index.js +3 -3
  134. package/lib/machine-learning/machine-learning-api-client.d.ts +1 -1
  135. package/lib/machine-learning/machine-learning-api-client.js +3 -3
  136. package/lib/machine-learning/machine-learning-namespace.d.ts +1 -1
  137. package/lib/machine-learning/machine-learning-namespace.js +1 -1
  138. package/lib/machine-learning/machine-learning-utils.d.ts +1 -1
  139. package/lib/machine-learning/machine-learning-utils.js +1 -1
  140. package/lib/machine-learning/machine-learning.d.ts +1 -1
  141. package/lib/machine-learning/machine-learning.js +1 -1
  142. package/lib/messaging/index.d.ts +2 -2
  143. package/lib/messaging/index.js +3 -3
  144. package/lib/messaging/messaging-api-request-internal.d.ts +2 -12
  145. package/lib/messaging/messaging-api-request-internal.js +4 -40
  146. package/lib/messaging/messaging-api.d.ts +8 -94
  147. package/lib/messaging/messaging-api.js +1 -1
  148. package/lib/messaging/messaging-errors-internal.d.ts +1 -1
  149. package/lib/messaging/messaging-errors-internal.js +3 -4
  150. package/lib/messaging/messaging-internal.d.ts +1 -1
  151. package/lib/messaging/messaging-internal.js +4 -3
  152. package/lib/messaging/messaging-namespace.d.ts +2 -22
  153. package/lib/messaging/messaging-namespace.js +1 -1
  154. package/lib/messaging/messaging.d.ts +3 -149
  155. package/lib/messaging/messaging.js +2 -539
  156. package/lib/project-management/android-app.d.ts +1 -1
  157. package/lib/project-management/android-app.js +1 -1
  158. package/lib/project-management/app-metadata.d.ts +1 -1
  159. package/lib/project-management/app-metadata.js +1 -1
  160. package/lib/project-management/index.d.ts +1 -1
  161. package/lib/project-management/index.js +3 -3
  162. package/lib/project-management/ios-app.d.ts +1 -1
  163. package/lib/project-management/ios-app.js +1 -1
  164. package/lib/project-management/project-management-api-request-internal.d.ts +1 -1
  165. package/lib/project-management/project-management-api-request-internal.js +3 -3
  166. package/lib/project-management/project-management-namespace.d.ts +1 -1
  167. package/lib/project-management/project-management-namespace.js +1 -1
  168. package/lib/project-management/project-management.d.ts +1 -1
  169. package/lib/project-management/project-management.js +1 -1
  170. package/lib/remote-config/condition-evaluator-internal.d.ts +1 -1
  171. package/lib/remote-config/condition-evaluator-internal.js +6 -14
  172. package/lib/remote-config/index.d.ts +1 -1
  173. package/lib/remote-config/index.js +3 -3
  174. package/lib/remote-config/internal/value-impl.d.ts +1 -1
  175. package/lib/remote-config/internal/value-impl.js +1 -1
  176. package/lib/remote-config/remote-config-api-client-internal.d.ts +1 -1
  177. package/lib/remote-config/remote-config-api-client-internal.js +1 -1
  178. package/lib/remote-config/remote-config-api.d.ts +1 -1
  179. package/lib/remote-config/remote-config-api.js +1 -1
  180. package/lib/remote-config/remote-config-namespace.d.ts +1 -1
  181. package/lib/remote-config/remote-config-namespace.js +1 -1
  182. package/lib/remote-config/remote-config.d.ts +1 -1
  183. package/lib/remote-config/remote-config.js +1 -1
  184. package/lib/security-rules/index.d.ts +1 -1
  185. package/lib/security-rules/index.js +3 -3
  186. package/lib/security-rules/security-rules-api-client-internal.d.ts +1 -1
  187. package/lib/security-rules/security-rules-api-client-internal.js +1 -1
  188. package/lib/security-rules/security-rules-internal.d.ts +1 -1
  189. package/lib/security-rules/security-rules-internal.js +1 -1
  190. package/lib/security-rules/security-rules-namespace.d.ts +1 -1
  191. package/lib/security-rules/security-rules-namespace.js +1 -1
  192. package/lib/security-rules/security-rules.d.ts +1 -2
  193. package/lib/security-rules/security-rules.js +1 -1
  194. package/lib/storage/index.d.ts +1 -1
  195. package/lib/storage/index.js +4 -4
  196. package/lib/storage/storage-namespace.d.ts +1 -1
  197. package/lib/storage/storage-namespace.js +1 -1
  198. package/lib/storage/storage.d.ts +1 -1
  199. package/lib/storage/storage.js +1 -1
  200. package/lib/storage/utils.d.ts +1 -1
  201. package/lib/storage/utils.js +2 -3
  202. package/lib/utils/api-request.d.ts +1 -5
  203. package/lib/utils/api-request.js +23 -8
  204. package/lib/utils/crypto-signer.d.ts +1 -2
  205. package/lib/utils/crypto-signer.js +3 -3
  206. package/lib/utils/deep-copy.d.ts +1 -1
  207. package/lib/utils/deep-copy.js +3 -4
  208. package/lib/utils/error.d.ts +1 -1
  209. package/lib/utils/error.js +1 -1
  210. package/lib/utils/index.d.ts +2 -2
  211. package/lib/utils/index.js +19 -16
  212. package/lib/utils/jwt.d.ts +1 -2
  213. package/lib/utils/jwt.js +5 -5
  214. package/lib/utils/validator.d.ts +1 -2
  215. package/lib/utils/validator.js +20 -21
  216. package/package.json +14 -13
  217. package/CHANGELOG.md +0 -4
  218. package/lib/messaging/batch-request-internal.d.ts +0 -55
  219. package/lib/messaging/batch-request-internal.js +0 -127
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v12.7.0 */
1
+ /*! firebase-admin v13.0.0 */
2
2
  "use strict";
3
3
  /*!
4
4
  * @license
@@ -17,37 +17,84 @@
17
17
  * limitations under the License.
18
18
  */
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.getApplicationDefault = exports.isApplicationDefault = exports.ImpersonatedServiceAccountCredential = exports.RefreshTokenCredential = exports.ComputeEngineCredential = exports.ServiceAccountCredential = void 0;
20
+ exports.ImpersonatedServiceAccountCredential = exports.RefreshTokenCredential = exports.ServiceAccountCredential = exports.ApplicationDefaultCredential = void 0;
21
+ exports.isApplicationDefault = isApplicationDefault;
22
+ exports.getApplicationDefault = getApplicationDefault;
21
23
  const fs = require("fs");
22
- const os = require("os");
23
- const path = require("path");
24
+ const google_auth_library_1 = require("google-auth-library");
24
25
  const error_1 = require("../utils/error");
25
- const api_request_1 = require("../utils/api-request");
26
26
  const util = require("../utils/validator");
27
- const GOOGLE_TOKEN_AUDIENCE = 'https://accounts.google.com/o/oauth2/token';
28
- const GOOGLE_AUTH_TOKEN_HOST = 'accounts.google.com';
29
- const GOOGLE_AUTH_TOKEN_PATH = '/o/oauth2/token';
30
- // NOTE: the Google Metadata Service uses HTTP over a vlan
31
- const GOOGLE_METADATA_SERVICE_HOST = 'metadata.google.internal';
32
- const GOOGLE_METADATA_SERVICE_TOKEN_PATH = '/computeMetadata/v1/instance/service-accounts/default/token';
33
- const GOOGLE_METADATA_SERVICE_IDENTITY_PATH = '/computeMetadata/v1/instance/service-accounts/default/identity';
34
- const GOOGLE_METADATA_SERVICE_PROJECT_ID_PATH = '/computeMetadata/v1/project/project-id';
35
- const GOOGLE_METADATA_SERVICE_ACCOUNT_ID_PATH = '/computeMetadata/v1/instance/service-accounts/default/email';
36
- const configDir = (() => {
37
- // Windows has a dedicated low-rights location for apps at ~/Application Data
38
- const sys = os.platform();
39
- if (sys && sys.length >= 3 && sys.substring(0, 3).toLowerCase() === 'win') {
40
- return process.env.APPDATA;
27
+ const SCOPES = [
28
+ 'https://www.googleapis.com/auth/cloud-platform',
29
+ 'https://www.googleapis.com/auth/firebase.database',
30
+ 'https://www.googleapis.com/auth/firebase.messaging',
31
+ 'https://www.googleapis.com/auth/identitytoolkit',
32
+ 'https://www.googleapis.com/auth/userinfo.email',
33
+ ];
34
+ /**
35
+ * Implementation of ADC that uses google-auth-library-nodejs.
36
+ */
37
+ class ApplicationDefaultCredential {
38
+ constructor(httpAgent) {
39
+ this.googleAuth = new google_auth_library_1.GoogleAuth({
40
+ scopes: SCOPES,
41
+ clientOptions: {
42
+ transporterOptions: {
43
+ agent: httpAgent,
44
+ },
45
+ },
46
+ });
47
+ }
48
+ async getAccessToken() {
49
+ if (!this.authClient) {
50
+ this.authClient = await this.googleAuth.getClient();
51
+ }
52
+ await this.authClient.getAccessToken();
53
+ const credentials = this.authClient.credentials;
54
+ this.quotaProjectId = this.authClient.quotaProjectId;
55
+ return populateCredential(credentials);
56
+ }
57
+ async getProjectId() {
58
+ if (!this.projectId) {
59
+ this.projectId = await this.googleAuth.getProjectId();
60
+ }
61
+ return Promise.resolve(this.projectId);
62
+ }
63
+ getQuotaProjectId() {
64
+ if (!this.quotaProjectId) {
65
+ this.quotaProjectId = this.authClient?.quotaProjectId;
66
+ }
67
+ return this.quotaProjectId;
68
+ }
69
+ async isComputeEngineCredential() {
70
+ if (!this.authClient) {
71
+ this.authClient = await this.googleAuth.getClient();
72
+ }
73
+ return Promise.resolve(this.authClient instanceof google_auth_library_1.Compute);
74
+ }
75
+ /**
76
+ * getIDToken returns a OIDC token from the compute metadata service
77
+ * that can be used to make authenticated calls to audience
78
+ * @param audience the URL the returned ID token will be used to call.
79
+ */
80
+ async getIDToken(audience) {
81
+ if (await this.isComputeEngineCredential()) {
82
+ return this.authClient.fetchIdToken(audience);
83
+ }
84
+ else {
85
+ throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Credentials type should be Compute Engine Credentials.');
86
+ }
87
+ }
88
+ async getServiceAccountEmail() {
89
+ if (this.accountId) {
90
+ return Promise.resolve(this.accountId);
91
+ }
92
+ const { client_email: clientEmail } = await this.googleAuth.getCredentials();
93
+ this.accountId = clientEmail ?? '';
94
+ return Promise.resolve(this.accountId);
41
95
  }
42
- // On *nix the gcloud cli creates a . dir.
43
- return process.env.HOME && path.resolve(process.env.HOME, '.config');
44
- })();
45
- const GCLOUD_CREDENTIAL_SUFFIX = 'gcloud/application_default_credentials.json';
46
- const GCLOUD_CREDENTIAL_PATH = configDir && path.resolve(configDir, GCLOUD_CREDENTIAL_SUFFIX);
47
- const REFRESH_TOKEN_HOST = 'www.googleapis.com';
48
- const REFRESH_TOKEN_PATH = '/oauth2/v4/token';
49
- const ONE_HOUR_IN_SECONDS = 60 * 60;
50
- const JWT_ALGORITHM = 'RS256';
96
+ }
97
+ exports.ApplicationDefaultCredential = ApplicationDefaultCredential;
51
98
  /**
52
99
  * Implementation of Credential that uses a service account.
53
100
  */
@@ -57,12 +104,13 @@ class ServiceAccountCredential {
57
104
  *
58
105
  * @param serviceAccountPathOrObject - Service account json object or path to a service account json file.
59
106
  * @param httpAgent - Optional http.Agent to use when calling the remote token server.
60
- * @param implicit - An optinal boolean indicating whether this credential was implicitly discovered from the
107
+ * @param implicit - An optional boolean indicating whether this credential was implicitly discovered from the
61
108
  * environment, as opposed to being explicitly specified by the developer.
62
109
  *
63
110
  * @constructor
64
111
  */
65
112
  constructor(serviceAccountPathOrObject, httpAgent, implicit = false) {
113
+ this.serviceAccountPathOrObject = serviceAccountPathOrObject;
66
114
  this.httpAgent = httpAgent;
67
115
  this.implicit = implicit;
68
116
  const serviceAccount = (typeof serviceAccountPathOrObject === 'string') ?
@@ -71,43 +119,24 @@ class ServiceAccountCredential {
71
119
  this.projectId = serviceAccount.projectId;
72
120
  this.privateKey = serviceAccount.privateKey;
73
121
  this.clientEmail = serviceAccount.clientEmail;
74
- this.httpClient = new api_request_1.HttpClient();
75
- }
76
- getAccessToken() {
77
- const token = this.createAuthJwt_();
78
- const postData = 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3A' +
79
- 'grant-type%3Ajwt-bearer&assertion=' + token;
80
- const request = {
81
- method: 'POST',
82
- url: `https://${GOOGLE_AUTH_TOKEN_HOST}${GOOGLE_AUTH_TOKEN_PATH}`,
83
- headers: {
84
- 'Content-Type': 'application/x-www-form-urlencoded',
85
- },
86
- data: postData,
87
- httpAgent: this.httpAgent,
88
- };
89
- return requestAccessToken(this.httpClient, request);
90
122
  }
91
- // eslint-disable-next-line @typescript-eslint/naming-convention
92
- createAuthJwt_() {
93
- const claims = {
94
- scope: [
95
- 'https://www.googleapis.com/auth/cloud-platform',
96
- 'https://www.googleapis.com/auth/firebase.database',
97
- 'https://www.googleapis.com/auth/firebase.messaging',
98
- 'https://www.googleapis.com/auth/identitytoolkit',
99
- 'https://www.googleapis.com/auth/userinfo.email',
100
- ].join(' '),
101
- };
102
- // eslint-disable-next-line @typescript-eslint/no-var-requires
103
- const jwt = require('jsonwebtoken');
104
- // This method is actually synchronous so we can capture and return the buffer.
105
- return jwt.sign(claims, this.privateKey, {
106
- audience: GOOGLE_TOKEN_AUDIENCE,
107
- expiresIn: ONE_HOUR_IN_SECONDS,
108
- issuer: this.clientEmail,
109
- algorithm: JWT_ALGORITHM,
110
- });
123
+ getGoogleAuth() {
124
+ if (this.googleAuth) {
125
+ return this.googleAuth;
126
+ }
127
+ const { auth, client } = populateGoogleAuth(this.serviceAccountPathOrObject, this.httpAgent);
128
+ this.googleAuth = auth;
129
+ this.authClient = client;
130
+ return this.googleAuth;
131
+ }
132
+ async getAccessToken() {
133
+ const googleAuth = this.getGoogleAuth();
134
+ if (this.authClient === undefined) {
135
+ this.authClient = await googleAuth.getClient();
136
+ }
137
+ await this.authClient.getAccessToken();
138
+ const credentials = this.authClient.credentials;
139
+ return populateCredential(credentials);
111
140
  }
112
141
  }
113
142
  exports.ServiceAccountCredential = ServiceAccountCredential;
@@ -154,71 +183,6 @@ class ServiceAccount {
154
183
  }
155
184
  }
156
185
  }
157
- /**
158
- * Implementation of Credential that gets access tokens from the metadata service available
159
- * in the Google Cloud Platform. This authenticates the process as the default service account
160
- * of an App Engine instance or Google Compute Engine machine.
161
- */
162
- class ComputeEngineCredential {
163
- constructor(httpAgent) {
164
- this.httpClient = new api_request_1.HttpClient();
165
- this.httpAgent = httpAgent;
166
- }
167
- getAccessToken() {
168
- const request = this.buildRequest(GOOGLE_METADATA_SERVICE_TOKEN_PATH);
169
- return requestAccessToken(this.httpClient, request);
170
- }
171
- /**
172
- * getIDToken returns a OIDC token from the compute metadata service
173
- * that can be used to make authenticated calls to audience
174
- * @param audience the URL the returned ID token will be used to call.
175
- */
176
- getIDToken(audience) {
177
- const request = this.buildRequest(`${GOOGLE_METADATA_SERVICE_IDENTITY_PATH}?audience=${audience}`);
178
- return requestIDToken(this.httpClient, request);
179
- }
180
- getProjectId() {
181
- if (this.projectId) {
182
- return Promise.resolve(this.projectId);
183
- }
184
- const request = this.buildRequest(GOOGLE_METADATA_SERVICE_PROJECT_ID_PATH);
185
- return this.httpClient.send(request)
186
- .then((resp) => {
187
- this.projectId = resp.text;
188
- return this.projectId;
189
- })
190
- .catch((err) => {
191
- const detail = (err instanceof api_request_1.RequestResponseError) ? getDetailFromResponse(err.response) : err.message;
192
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, `Failed to determine project ID: ${detail}`);
193
- });
194
- }
195
- getServiceAccountEmail() {
196
- if (this.accountId) {
197
- return Promise.resolve(this.accountId);
198
- }
199
- const request = this.buildRequest(GOOGLE_METADATA_SERVICE_ACCOUNT_ID_PATH);
200
- return this.httpClient.send(request)
201
- .then((resp) => {
202
- this.accountId = resp.text;
203
- return this.accountId;
204
- })
205
- .catch((err) => {
206
- const detail = (err instanceof api_request_1.RequestResponseError) ? getDetailFromResponse(err.response) : err.message;
207
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, `Failed to determine service account email: ${detail}`);
208
- });
209
- }
210
- buildRequest(urlPath) {
211
- return {
212
- method: 'GET',
213
- url: `http://${GOOGLE_METADATA_SERVICE_HOST}${urlPath}`,
214
- headers: {
215
- 'Metadata-Flavor': 'Google',
216
- },
217
- httpAgent: this.httpAgent,
218
- };
219
- }
220
- }
221
- exports.ComputeEngineCredential = ComputeEngineCredential;
222
186
  /**
223
187
  * Implementation of Credential that gets access tokens from refresh tokens.
224
188
  */
@@ -235,28 +199,30 @@ class RefreshTokenCredential {
235
199
  * @constructor
236
200
  */
237
201
  constructor(refreshTokenPathOrObject, httpAgent, implicit = false) {
202
+ this.refreshTokenPathOrObject = refreshTokenPathOrObject;
238
203
  this.httpAgent = httpAgent;
239
204
  this.implicit = implicit;
240
- this.refreshToken = (typeof refreshTokenPathOrObject === 'string') ?
241
- RefreshToken.fromPath(refreshTokenPathOrObject)
242
- : new RefreshToken(refreshTokenPathOrObject);
243
- this.httpClient = new api_request_1.HttpClient();
205
+ (typeof refreshTokenPathOrObject === 'string') ?
206
+ RefreshToken.validateFromPath(refreshTokenPathOrObject)
207
+ : RefreshToken.validateFromJSON(refreshTokenPathOrObject);
244
208
  }
245
- getAccessToken() {
246
- const postData = 'client_id=' + this.refreshToken.clientId + '&' +
247
- 'client_secret=' + this.refreshToken.clientSecret + '&' +
248
- 'refresh_token=' + this.refreshToken.refreshToken + '&' +
249
- 'grant_type=refresh_token';
250
- const request = {
251
- method: 'POST',
252
- url: `https://${REFRESH_TOKEN_HOST}${REFRESH_TOKEN_PATH}`,
253
- headers: {
254
- 'Content-Type': 'application/x-www-form-urlencoded',
255
- },
256
- data: postData,
257
- httpAgent: this.httpAgent,
258
- };
259
- return requestAccessToken(this.httpClient, request);
209
+ getGoogleAuth() {
210
+ if (this.googleAuth) {
211
+ return this.googleAuth;
212
+ }
213
+ const { auth, client } = populateGoogleAuth(this.refreshTokenPathOrObject, this.httpAgent);
214
+ this.googleAuth = auth;
215
+ this.authClient = client;
216
+ return this.googleAuth;
217
+ }
218
+ async getAccessToken() {
219
+ const googleAuth = this.getGoogleAuth();
220
+ if (this.authClient === undefined) {
221
+ this.authClient = await googleAuth.getClient();
222
+ }
223
+ await this.authClient.getAccessToken();
224
+ const credentials = this.authClient.credentials;
225
+ return populateCredential(credentials);
260
226
  }
261
227
  }
262
228
  exports.RefreshTokenCredential = RefreshTokenCredential;
@@ -265,31 +231,32 @@ class RefreshToken {
265
231
  * Tries to load a RefreshToken from a path. Throws if the path doesn't exist or the
266
232
  * data at the path is invalid.
267
233
  */
268
- static fromPath(filePath) {
234
+ static validateFromPath(filePath) {
269
235
  try {
270
- return new RefreshToken(JSON.parse(fs.readFileSync(filePath, 'utf8')));
236
+ RefreshToken.validateFromJSON(JSON.parse(fs.readFileSync(filePath, 'utf8')));
271
237
  }
272
238
  catch (error) {
273
239
  // Throw a nicely formed error message if the file contents cannot be parsed
274
240
  throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse refresh token file: ' + error);
275
241
  }
276
242
  }
277
- constructor(json) {
278
- copyAttr(this, json, 'clientId', 'client_id');
279
- copyAttr(this, json, 'clientSecret', 'client_secret');
280
- copyAttr(this, json, 'refreshToken', 'refresh_token');
281
- copyAttr(this, json, 'type', 'type');
243
+ static validateFromJSON(json) {
244
+ const creds = { clientId: '', clientSecret: '', refreshToken: '', type: '' };
245
+ copyAttr(creds, json, 'clientId', 'client_id');
246
+ copyAttr(creds, json, 'clientSecret', 'client_secret');
247
+ copyAttr(creds, json, 'refreshToken', 'refresh_token');
248
+ copyAttr(creds, json, 'type', 'type');
282
249
  let errorMessage;
283
- if (!util.isNonEmptyString(this.clientId)) {
250
+ if (!util.isNonEmptyString(creds.clientId)) {
284
251
  errorMessage = 'Refresh token must contain a "client_id" property.';
285
252
  }
286
- else if (!util.isNonEmptyString(this.clientSecret)) {
253
+ else if (!util.isNonEmptyString(creds.clientSecret)) {
287
254
  errorMessage = 'Refresh token must contain a "client_secret" property.';
288
255
  }
289
- else if (!util.isNonEmptyString(this.refreshToken)) {
256
+ else if (!util.isNonEmptyString(creds.refreshToken)) {
290
257
  errorMessage = 'Refresh token must contain a "refresh_token" property.';
291
258
  }
292
- else if (!util.isNonEmptyString(this.type)) {
259
+ else if (!util.isNonEmptyString(creds.type)) {
293
260
  errorMessage = 'Refresh token must contain a "type" property.';
294
261
  }
295
262
  if (typeof errorMessage !== 'undefined') {
@@ -313,67 +280,63 @@ class ImpersonatedServiceAccountCredential {
313
280
  * @constructor
314
281
  */
315
282
  constructor(impersonatedServiceAccountPathOrObject, httpAgent, implicit = false) {
283
+ this.impersonatedServiceAccountPathOrObject = impersonatedServiceAccountPathOrObject;
316
284
  this.httpAgent = httpAgent;
317
285
  this.implicit = implicit;
318
- this.impersonatedServiceAccount = (typeof impersonatedServiceAccountPathOrObject === 'string') ?
319
- ImpersonatedServiceAccount.fromPath(impersonatedServiceAccountPathOrObject)
320
- : new ImpersonatedServiceAccount(impersonatedServiceAccountPathOrObject);
321
- this.httpClient = new api_request_1.HttpClient();
286
+ (typeof impersonatedServiceAccountPathOrObject === 'string') ?
287
+ ImpersonatedServiceAccount.validateFromPath(impersonatedServiceAccountPathOrObject)
288
+ : ImpersonatedServiceAccount.validateFromJSON(impersonatedServiceAccountPathOrObject);
322
289
  }
323
- getAccessToken() {
324
- const postData = 'client_id=' + this.impersonatedServiceAccount.clientId + '&' +
325
- 'client_secret=' + this.impersonatedServiceAccount.clientSecret + '&' +
326
- 'refresh_token=' + this.impersonatedServiceAccount.refreshToken + '&' +
327
- 'grant_type=refresh_token';
328
- const request = {
329
- method: 'POST',
330
- url: `https://${REFRESH_TOKEN_HOST}${REFRESH_TOKEN_PATH}`,
331
- headers: {
332
- 'Content-Type': 'application/x-www-form-urlencoded',
333
- },
334
- data: postData,
335
- httpAgent: this.httpAgent,
336
- };
337
- return requestAccessToken(this.httpClient, request);
290
+ getGoogleAuth() {
291
+ if (this.googleAuth) {
292
+ return this.googleAuth;
293
+ }
294
+ const { auth, client } = populateGoogleAuth(this.impersonatedServiceAccountPathOrObject, this.httpAgent);
295
+ this.googleAuth = auth;
296
+ this.authClient = client;
297
+ return this.googleAuth;
298
+ }
299
+ async getAccessToken() {
300
+ const googleAuth = this.getGoogleAuth();
301
+ if (this.authClient === undefined) {
302
+ this.authClient = await googleAuth.getClient();
303
+ }
304
+ await this.authClient.getAccessToken();
305
+ const credentials = this.authClient.credentials;
306
+ return populateCredential(credentials);
338
307
  }
339
308
  }
340
309
  exports.ImpersonatedServiceAccountCredential = ImpersonatedServiceAccountCredential;
341
310
  /**
342
- * A struct containing the properties necessary to use impersonated service account JSON credentials.
311
+ * A helper class to validate the properties necessary to use impersonated service account credentials.
343
312
  */
344
313
  class ImpersonatedServiceAccount {
345
314
  /*
346
315
  * Tries to load a ImpersonatedServiceAccount from a path. Throws if the path doesn't exist or the
347
316
  * data at the path is invalid.
348
317
  */
349
- static fromPath(filePath) {
318
+ static validateFromPath(filePath) {
350
319
  try {
351
- return new ImpersonatedServiceAccount(JSON.parse(fs.readFileSync(filePath, 'utf8')));
320
+ ImpersonatedServiceAccount.validateFromJSON(JSON.parse(fs.readFileSync(filePath, 'utf8')));
352
321
  }
353
322
  catch (error) {
354
323
  // Throw a nicely formed error message if the file contents cannot be parsed
355
324
  throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse impersonated service account file: ' + error);
356
325
  }
357
326
  }
358
- constructor(json) {
359
- const sourceCredentials = json['source_credentials'];
360
- if (sourceCredentials) {
361
- copyAttr(this, sourceCredentials, 'clientId', 'client_id');
362
- copyAttr(this, sourceCredentials, 'clientSecret', 'client_secret');
363
- copyAttr(this, sourceCredentials, 'refreshToken', 'refresh_token');
364
- copyAttr(this, sourceCredentials, 'type', 'type');
365
- }
327
+ static validateFromJSON(json) {
328
+ const { client_id: clientId, client_secret: clientSecret, refresh_token: refreshToken, type } = json['source_credentials'];
366
329
  let errorMessage;
367
- if (!util.isNonEmptyString(this.clientId)) {
330
+ if (!util.isNonEmptyString(clientId)) {
368
331
  errorMessage = 'Impersonated Service Account must contain a "source_credentials.client_id" property.';
369
332
  }
370
- else if (!util.isNonEmptyString(this.clientSecret)) {
333
+ else if (!util.isNonEmptyString(clientSecret)) {
371
334
  errorMessage = 'Impersonated Service Account must contain a "source_credentials.client_secret" property.';
372
335
  }
373
- else if (!util.isNonEmptyString(this.refreshToken)) {
336
+ else if (!util.isNonEmptyString(refreshToken)) {
374
337
  errorMessage = 'Impersonated Service Account must contain a "source_credentials.refresh_token" property.';
375
338
  }
376
- else if (!util.isNonEmptyString(this.type)) {
339
+ else if (!util.isNonEmptyString(type)) {
377
340
  errorMessage = 'Impersonated Service Account must contain a "source_credentials.type" property.';
378
341
  }
379
342
  if (typeof errorMessage !== 'undefined') {
@@ -382,33 +345,17 @@ class ImpersonatedServiceAccount {
382
345
  }
383
346
  }
384
347
  /**
385
- * Checks if the given credential was loaded via the application default credentials mechanism. This
386
- * includes all ComputeEngineCredential instances, and the ServiceAccountCredential and RefreshTokenCredential
387
- * instances that were loaded from well-known files or environment variables, rather than being explicitly
388
- * instantiated.
348
+ * Checks if the given credential was loaded via the application default credentials mechanism.
389
349
  *
390
350
  * @param credential - The credential instance to check.
391
351
  */
392
352
  function isApplicationDefault(credential) {
393
- return credential instanceof ComputeEngineCredential ||
394
- (credential instanceof ServiceAccountCredential && credential.implicit) ||
395
- (credential instanceof RefreshTokenCredential && credential.implicit) ||
396
- (credential instanceof ImpersonatedServiceAccountCredential && credential.implicit);
353
+ return credential instanceof ApplicationDefaultCredential ||
354
+ (credential instanceof RefreshTokenCredential && credential.implicit);
397
355
  }
398
- exports.isApplicationDefault = isApplicationDefault;
399
356
  function getApplicationDefault(httpAgent) {
400
- if (process.env.GOOGLE_APPLICATION_CREDENTIALS) {
401
- return credentialFromFile(process.env.GOOGLE_APPLICATION_CREDENTIALS, httpAgent, false);
402
- }
403
- // It is OK to not have this file. If it is present, it must be valid.
404
- if (GCLOUD_CREDENTIAL_PATH) {
405
- const credential = credentialFromFile(GCLOUD_CREDENTIAL_PATH, httpAgent, true);
406
- if (credential)
407
- return credential;
408
- }
409
- return new ComputeEngineCredential(httpAgent);
357
+ return new ApplicationDefaultCredential(httpAgent);
410
358
  }
411
- exports.getApplicationDefault = getApplicationDefault;
412
359
  /**
413
360
  * Copies the specified property from one object to another.
414
361
  *
@@ -427,89 +374,42 @@ function copyAttr(to, from, key, alt) {
427
374
  }
428
375
  }
429
376
  /**
430
- * Obtain a new OAuth2 token by making a remote service call.
377
+ * Populate google-auth-library GoogleAuth credentials type.
431
378
  */
432
- function requestAccessToken(client, request) {
433
- return client.send(request).then((resp) => {
434
- const json = resp.data;
435
- if (!json.access_token || !json.expires_in) {
436
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, `Unexpected response while fetching access token: ${JSON.stringify(json)}`);
437
- }
438
- return json;
439
- }).catch((err) => {
440
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, getErrorMessage(err));
441
- });
442
- }
443
- /**
444
- * Obtain a new OIDC token by making a remote service call.
445
- */
446
- function requestIDToken(client, request) {
447
- return client.send(request).then((resp) => {
448
- if (!resp.text) {
449
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Unexpected response while fetching id token: response.text is undefined');
450
- }
451
- return resp.text;
452
- }).catch((err) => {
453
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, getErrorMessage(err));
379
+ function populateGoogleAuth(keyFile, httpAgent) {
380
+ let client;
381
+ const auth = new google_auth_library_1.GoogleAuth({
382
+ scopes: SCOPES,
383
+ clientOptions: {
384
+ transporterOptions: {
385
+ agent: httpAgent,
386
+ },
387
+ },
388
+ keyFile: (typeof keyFile === 'string') ? keyFile : undefined,
454
389
  });
455
- }
456
- /**
457
- * Constructs a human-readable error message from the given Error.
458
- */
459
- function getErrorMessage(err) {
460
- const detail = (err instanceof api_request_1.RequestResponseError) ? getDetailFromResponse(err.response) : err.message;
461
- return `Error fetching access token: ${detail}`;
462
- }
463
- /**
464
- * Extracts details from the given HTTP error response, and returns a human-readable description. If
465
- * the response is JSON-formatted, looks up the error and error_description fields sent by the
466
- * Google Auth servers. Otherwise returns the entire response payload as the error detail.
467
- */
468
- function getDetailFromResponse(response) {
469
- if (response.isJson() && response.data.error) {
470
- const json = response.data;
471
- let detail = json.error;
472
- if (json.error_description) {
473
- detail += ' (' + json.error_description + ')';
474
- }
475
- return detail;
476
- }
477
- return response.text || 'Missing error payload';
478
- }
479
- function credentialFromFile(filePath, httpAgent, ignoreMissing) {
480
- const credentialsFile = readCredentialFile(filePath, ignoreMissing);
481
- if (typeof credentialsFile !== 'object' || credentialsFile === null) {
482
- if (ignoreMissing) {
483
- return null;
390
+ if (typeof keyFile === 'object') {
391
+ if (!util.isNonNullObject(keyFile)) {
392
+ throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Service account must be an object.');
484
393
  }
485
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse contents of the credentials file as an object');
394
+ client = auth.fromJSON(keyFile);
486
395
  }
487
- if (credentialsFile.type === 'service_account') {
488
- return new ServiceAccountCredential(credentialsFile, httpAgent, true);
489
- }
490
- if (credentialsFile.type === 'authorized_user') {
491
- return new RefreshTokenCredential(credentialsFile, httpAgent, true);
492
- }
493
- if (credentialsFile.type === 'impersonated_service_account') {
494
- return new ImpersonatedServiceAccountCredential(credentialsFile, httpAgent, true);
495
- }
496
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Invalid contents in the credentials file');
396
+ return { auth, client };
497
397
  }
498
- function readCredentialFile(filePath, ignoreMissing) {
499
- let fileText;
500
- try {
501
- fileText = fs.readFileSync(filePath, 'utf8');
502
- }
503
- catch (error) {
504
- if (ignoreMissing) {
505
- return null;
506
- }
507
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, `Failed to read credentials from file ${filePath}: ` + error);
508
- }
509
- try {
510
- return JSON.parse(fileText);
511
- }
512
- catch (error) {
513
- throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse contents of the credentials file as an object: ' + error);
514
- }
398
+ /**
399
+ * Populate GoogleOAuthAccessToken credentials from google-auth-library Credentials type.
400
+ */
401
+ function populateCredential(credentials) {
402
+ const accessToken = credentials?.access_token;
403
+ const expiryDate = credentials?.expiry_date;
404
+ if (typeof accessToken !== 'string')
405
+ throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse Google auth credential: access_token must be a non empty string.');
406
+ if (typeof expiryDate !== 'number')
407
+ throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse Google auth credential: Invalid expiry_date.');
408
+ return {
409
+ ...credentials,
410
+ access_token: accessToken,
411
+ // inverse operation of following
412
+ // https://github.com/googleapis/google-auth-library-nodejs/blob/5ed910513451c82e2551777a3e2212964799ef8e/src/auth/baseexternalclient.ts#L446-L446
413
+ expires_in: Math.floor((expiryDate - new Date().getTime()) / 1000),
414
+ };
515
415
  }
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v12.7.0 */
1
+ /*! firebase-admin v13.0.0 */
2
2
  /*!
3
3
  * @license
4
4
  * Copyright 2021 Google Inc.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v12.7.0 */
1
+ /*! firebase-admin v13.0.0 */
2
2
  "use strict";
3
3
  /*!
4
4
  * @license
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v12.7.0 */
1
+ /*! firebase-admin v13.0.0 */
2
2
  /*!
3
3
  * @license
4
4
  * Copyright 2017 Google Inc.
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v12.7.0 */
1
+ /*! firebase-admin v13.0.0 */
2
2
  "use strict";
3
3
  /*!
4
4
  * @license
@@ -1,4 +1,4 @@
1
- /*! firebase-admin v12.7.0 */
1
+ /*! firebase-admin v13.0.0 */
2
2
  /*!
3
3
  * @license
4
4
  * Copyright 2017 Google Inc.