initial commit

This commit is contained in:
2025-09-01 22:12:29 +02:00
parent b1873f9c1d
commit 02a54f61c0
5598 changed files with 903558 additions and 0 deletions

187
server/node_modules/firebase-admin/lib/app/core.d.ts generated vendored Normal file
View File

@@ -0,0 +1,187 @@
/*! firebase-admin v13.5.0 */
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Agent } from 'http';
import { Credential } from './credential';
/**
* Available options to pass to {@link firebase-admin.app#initializeApp}.
*/
export interface AppOptions {
/**
* A {@link firebase-admin.app#Credential} object used to
* authenticate the Admin SDK.
*
* See {@link https://firebase.google.com/docs/admin/setup#initialize_the_sdk | Initialize the SDK}
* for detailed documentation and code samples.
*/
credential?: Credential;
/**
* The object to use as the {@link https://firebase.google.com/docs/reference/security/database/#auth | auth}
* variable in your Realtime Database Rules when the Admin SDK reads from or
* writes to the Realtime Database. This allows you to downscope the Admin SDK
* from its default full read and write privileges.
*
* You can pass `null` to act as an unauthenticated client.
*
* See
* {@link https://firebase.google.com/docs/database/admin/start#authenticate-with-limited-privileges |
* Authenticate with limited privileges}
* for detailed documentation and code samples.
*/
databaseAuthVariableOverride?: object | null;
/**
* The URL of the Realtime Database from which to read and write data.
*/
databaseURL?: string;
/**
* The ID of the service account to be used for signing custom tokens. This
* can be found in the `client_email` field of a service account JSON file.
*/
serviceAccountId?: string;
/**
* The name of the Google Cloud Storage bucket used for storing application data.
* Use only the bucket name without any prefixes or additions (do *not* prefix
* the name with "gs://").
*/
storageBucket?: string;
/**
* The ID of the Google Cloud project associated with the App.
*/
projectId?: string;
/**
* An {@link https://nodejs.org/api/http.html#http_class_http_agent | HTTP Agent}
* to be used when making outgoing HTTP calls. This Agent instance is used
* by all services that make REST calls (e.g. `auth`, `messaging`,
* `projectManagement`).
*
* Realtime Database and Firestore use other means of communicating with
* the backend servers, so they do not use this HTTP Agent. `Credential`
* instances also do not use this HTTP Agent, but instead support
* specifying an HTTP Agent in the corresponding factory methods.
*/
httpAgent?: Agent;
}
/**
* A Firebase app holds the initialization information for a collection of
* services.
*/
export interface App {
/**
* The (read-only) name for this app.
*
* The default app's name is `"[DEFAULT]"`.
*
* @example
* ```javascript
* // The default app's name is "[DEFAULT]"
* initializeApp(defaultAppConfig);
* console.log(admin.app().name); // "[DEFAULT]"
* ```
*
* @example
* ```javascript
* // A named app's name is what you provide to initializeApp()
* const otherApp = initializeApp(otherAppConfig, "other");
* console.log(otherApp.name); // "other"
* ```
*/
name: string;
/**
* The (read-only) configuration options for this app. These are the original
* parameters given in {@link firebase-admin.app#initializeApp}.
*
* @example
* ```javascript
* const app = initializeApp(config);
* console.log(app.options.credential === config.credential); // true
* console.log(app.options.databaseURL === config.databaseURL); // true
* ```
*/
options: AppOptions;
}
/**
* `FirebaseError` is a subclass of the standard JavaScript `Error` object. In
* addition to a message string and stack trace, it contains a string code.
*/
export interface FirebaseError {
/**
* Error codes are strings using the following format: `"service/string-code"`.
* Some examples include `"auth/invalid-uid"` and
* `"messaging/invalid-recipient"`.
*
* While the message for a given error can change, the code will remain the same
* between backward-compatible versions of the Firebase SDK.
*/
code: string;
/**
* An explanatory message for the error that just occurred.
*
* This message is designed to be helpful to you, the developer. Because
* it generally does not convey meaningful information to end users,
* this message should not be displayed in your application.
*/
message: string;
/**
* A string value containing the execution backtrace when the error originally
* occurred.
*
* This information can be useful for troubleshooting the cause of the error with
* {@link https://firebase.google.com/support | Firebase Support}.
*/
stack?: string;
/**
* Returns a JSON-serializable object representation of this error.
*
* @returns A JSON-serializable representation of this object.
*/
toJSON(): object;
}
/**
* Composite type which includes both a `FirebaseError` object and an index
* which can be used to get the errored item.
*
* @example
* ```javascript
* var registrationTokens = [token1, token2, token3];
* admin.messaging().subscribeToTopic(registrationTokens, 'topic-name')
* .then(function(response) {
* if (response.failureCount > 0) {
* console.log("Following devices unsucessfully subscribed to topic:");
* response.errors.forEach(function(error) {
* var invalidToken = registrationTokens[error.index];
* console.log(invalidToken, error.error);
* });
* } else {
* console.log("All devices successfully subscribed to topic:", response);
* }
* })
* .catch(function(error) {
* console.log("Error subscribing to topic:", error);
* });
*```
*/
export interface FirebaseArrayIndexError {
/**
* The index of the errored item within the original array passed as part of the
* called API method.
*/
index: number;
/**
* The error object.
*/
error: FirebaseError;
}

19
server/node_modules/firebase-admin/lib/app/core.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/*! firebase-admin v13.5.0 */
"use strict";
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,122 @@
/*! firebase-admin v13.5.0 */
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Agent } from 'http';
import { Credential, ServiceAccount } from './credential';
/**
* Returns a credential created from the
* {@link https://developers.google.com/identity/protocols/application-default-credentials |
* Google Application Default Credentials}
* that grants admin access to Firebase services. This credential can be used
* in the call to {@link firebase-admin.app#initializeApp}.
*
* Google Application Default Credentials are available on any Google
* infrastructure, such as Google App Engine and Google Compute Engine.
*
* See
* {@link https://firebase.google.com/docs/admin/setup#initialize_the_sdk | Initialize the SDK}
* for more details.
*
* @example
* ```javascript
* initializeApp({
* credential: applicationDefault(),
* databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
* });
* ```
*
* @param httpAgent - Optional {@link https://nodejs.org/api/http.html#http_class_http_agent | HTTP Agent}
* to be used when retrieving access tokens from Google token servers.
*
* @returns A credential authenticated via Google
* Application Default Credentials that can be used to initialize an app.
*/
export declare function applicationDefault(httpAgent?: Agent): Credential;
/**
* Returns a credential created from the provided service account that grants
* admin access to Firebase services. This credential can be used in the call
* to {@link firebase-admin.app#initializeApp}.
*
* See
* {@link https://firebase.google.com/docs/admin/setup#initialize_the_sdk | Initialize the SDK}
* for more details.
*
* @example
* ```javascript
* // Providing a path to a service account key JSON file
* const serviceAccount = require("path/to/serviceAccountKey.json");
* initializeApp({
* credential: cert(serviceAccount),
* databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
* });
* ```
*
* @example
* ```javascript
* // Providing a service account object inline
* initializeApp({
* credential: cert({
* projectId: "<PROJECT_ID>",
* clientEmail: "foo@<PROJECT_ID>.iam.gserviceaccount.com",
* privateKey: "-----BEGIN PRIVATE KEY-----<KEY>-----END PRIVATE KEY-----\n"
* }),
* databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
* });
* ```
*
* @param serviceAccountPathOrObject - The path to a service
* account key JSON file or an object representing a service account key.
* @param httpAgent - Optional {@link https://nodejs.org/api/http.html#http_class_http_agent | HTTP Agent}
* to be used when retrieving access tokens from Google token servers.
*
* @returns A credential authenticated via the
* provided service account that can be used to initialize an app.
*/
export declare function cert(serviceAccountPathOrObject: string | ServiceAccount, httpAgent?: Agent): Credential;
/**
* Returns a credential created from the provided refresh token that grants
* admin access to Firebase services. This credential can be used in the call
* to {@link firebase-admin.app#initializeApp}.
*
* See
* {@link https://firebase.google.com/docs/admin/setup#initialize_the_sdk | Initialize the SDK}
* for more details.
*
* @example
* ```javascript
* // Providing a path to a refresh token JSON file
* const refreshToken = require("path/to/refreshToken.json");
* initializeApp({
* credential: refreshToken(refreshToken),
* databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
* });
* ```
*
* @param refreshTokenPathOrObject - The path to a Google
* OAuth2 refresh token JSON file or an object representing a Google OAuth2
* refresh token.
* @param httpAgent - Optional {@link https://nodejs.org/api/http.html#http_class_http_agent | HTTP Agent}
* to be used when retrieving access tokens from Google token servers.
*
* @returns A credential authenticated via the
* provided service account that can be used to initialize an app.
*/
export declare function refreshToken(refreshTokenPathOrObject: string | object, httpAgent?: Agent): Credential;
/**
* Clears the global ADC cache. Exported for testing.
*/
export declare function clearGlobalAppDefaultCred(): void;

View File

@@ -0,0 +1,149 @@
/*! firebase-admin v13.5.0 */
"use strict";
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.applicationDefault = applicationDefault;
exports.cert = cert;
exports.refreshToken = refreshToken;
exports.clearGlobalAppDefaultCred = clearGlobalAppDefaultCred;
const credential_internal_1 = require("./credential-internal");
let globalAppDefaultCred;
const globalCertCreds = {};
const globalRefreshTokenCreds = {};
/**
* Returns a credential created from the
* {@link https://developers.google.com/identity/protocols/application-default-credentials |
* Google Application Default Credentials}
* that grants admin access to Firebase services. This credential can be used
* in the call to {@link firebase-admin.app#initializeApp}.
*
* Google Application Default Credentials are available on any Google
* infrastructure, such as Google App Engine and Google Compute Engine.
*
* See
* {@link https://firebase.google.com/docs/admin/setup#initialize_the_sdk | Initialize the SDK}
* for more details.
*
* @example
* ```javascript
* initializeApp({
* credential: applicationDefault(),
* databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
* });
* ```
*
* @param httpAgent - Optional {@link https://nodejs.org/api/http.html#http_class_http_agent | HTTP Agent}
* to be used when retrieving access tokens from Google token servers.
*
* @returns A credential authenticated via Google
* Application Default Credentials that can be used to initialize an app.
*/
function applicationDefault(httpAgent) {
if (typeof globalAppDefaultCred === 'undefined') {
globalAppDefaultCred = (0, credential_internal_1.getApplicationDefault)(httpAgent);
}
return globalAppDefaultCred;
}
/**
* Returns a credential created from the provided service account that grants
* admin access to Firebase services. This credential can be used in the call
* to {@link firebase-admin.app#initializeApp}.
*
* See
* {@link https://firebase.google.com/docs/admin/setup#initialize_the_sdk | Initialize the SDK}
* for more details.
*
* @example
* ```javascript
* // Providing a path to a service account key JSON file
* const serviceAccount = require("path/to/serviceAccountKey.json");
* initializeApp({
* credential: cert(serviceAccount),
* databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
* });
* ```
*
* @example
* ```javascript
* // Providing a service account object inline
* initializeApp({
* credential: cert({
* projectId: "<PROJECT_ID>",
* clientEmail: "foo@<PROJECT_ID>.iam.gserviceaccount.com",
* privateKey: "-----BEGIN PRIVATE KEY-----<KEY>-----END PRIVATE KEY-----\n"
* }),
* databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
* });
* ```
*
* @param serviceAccountPathOrObject - The path to a service
* account key JSON file or an object representing a service account key.
* @param httpAgent - Optional {@link https://nodejs.org/api/http.html#http_class_http_agent | HTTP Agent}
* to be used when retrieving access tokens from Google token servers.
*
* @returns A credential authenticated via the
* provided service account that can be used to initialize an app.
*/
function cert(serviceAccountPathOrObject, httpAgent) {
const stringifiedServiceAccount = JSON.stringify(serviceAccountPathOrObject);
if (!(stringifiedServiceAccount in globalCertCreds)) {
globalCertCreds[stringifiedServiceAccount] = new credential_internal_1.ServiceAccountCredential(serviceAccountPathOrObject, httpAgent);
}
return globalCertCreds[stringifiedServiceAccount];
}
/**
* Returns a credential created from the provided refresh token that grants
* admin access to Firebase services. This credential can be used in the call
* to {@link firebase-admin.app#initializeApp}.
*
* See
* {@link https://firebase.google.com/docs/admin/setup#initialize_the_sdk | Initialize the SDK}
* for more details.
*
* @example
* ```javascript
* // Providing a path to a refresh token JSON file
* const refreshToken = require("path/to/refreshToken.json");
* initializeApp({
* credential: refreshToken(refreshToken),
* databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
* });
* ```
*
* @param refreshTokenPathOrObject - The path to a Google
* OAuth2 refresh token JSON file or an object representing a Google OAuth2
* refresh token.
* @param httpAgent - Optional {@link https://nodejs.org/api/http.html#http_class_http_agent | HTTP Agent}
* to be used when retrieving access tokens from Google token servers.
*
* @returns A credential authenticated via the
* provided service account that can be used to initialize an app.
*/
function refreshToken(refreshTokenPathOrObject, httpAgent) {
const stringifiedRefreshToken = JSON.stringify(refreshTokenPathOrObject);
if (!(stringifiedRefreshToken in globalRefreshTokenCreds)) {
globalRefreshTokenCreds[stringifiedRefreshToken] = new credential_internal_1.RefreshTokenCredential(refreshTokenPathOrObject, httpAgent);
}
return globalRefreshTokenCreds[stringifiedRefreshToken];
}
/**
* Clears the global ADC cache. Exported for testing.
*/
function clearGlobalAppDefaultCred() {
globalAppDefaultCred = undefined;
}

View File

@@ -0,0 +1,122 @@
/*! firebase-admin v13.5.0 */
/*!
* @license
* Copyright 2020 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Agent } from 'http';
import { Credential, GoogleOAuthAccessToken } from './credential';
/**
* Implementation of ADC that uses google-auth-library-nodejs.
*/
export declare class ApplicationDefaultCredential implements Credential {
private readonly googleAuth;
private authClient;
private projectId?;
private quotaProjectId?;
private accountId?;
constructor(httpAgent?: Agent);
getAccessToken(): Promise<GoogleOAuthAccessToken>;
getProjectId(): Promise<string>;
getQuotaProjectId(): string | undefined;
isComputeEngineCredential(): Promise<boolean>;
/**
* getIDToken returns a OIDC token from the compute metadata service
* that can be used to make authenticated calls to audience
* @param audience the URL the returned ID token will be used to call.
*/
getIDToken(audience: string): Promise<string>;
getServiceAccountEmail(): Promise<string>;
}
/**
* Implementation of Credential that uses a service account.
*/
export declare class ServiceAccountCredential implements Credential {
private readonly serviceAccountPathOrObject;
private readonly httpAgent?;
readonly implicit: boolean;
readonly projectId: string;
readonly privateKey: string;
readonly clientEmail: string;
private googleAuth;
private authClient;
/**
* Creates a new ServiceAccountCredential from the given parameters.
*
* @param serviceAccountPathOrObject - Service account json object or path to a service account json file.
* @param httpAgent - Optional http.Agent to use when calling the remote token server.
* @param implicit - An optional boolean indicating whether this credential was implicitly discovered from the
* environment, as opposed to being explicitly specified by the developer.
*
* @constructor
*/
constructor(serviceAccountPathOrObject: string | object, httpAgent?: Agent | undefined, implicit?: boolean);
private getGoogleAuth;
getAccessToken(): Promise<GoogleOAuthAccessToken>;
}
/**
* Implementation of Credential that gets access tokens from refresh tokens.
*/
export declare class RefreshTokenCredential implements Credential {
private readonly refreshTokenPathOrObject;
private readonly httpAgent?;
readonly implicit: boolean;
private googleAuth;
private authClient;
/**
* Creates a new RefreshTokenCredential from the given parameters.
*
* @param refreshTokenPathOrObject - Refresh token json object or path to a refresh token
* (user credentials) json file.
* @param httpAgent - Optional http.Agent to use when calling the remote token server.
* @param implicit - An optinal boolean indicating whether this credential was implicitly
* discovered from the environment, as opposed to being explicitly specified by the developer.
*
* @constructor
*/
constructor(refreshTokenPathOrObject: string | object, httpAgent?: Agent | undefined, implicit?: boolean);
private getGoogleAuth;
getAccessToken(): Promise<GoogleOAuthAccessToken>;
}
/**
* Implementation of Credential that uses impersonated service account.
*/
export declare class ImpersonatedServiceAccountCredential implements Credential {
private readonly impersonatedServiceAccountPathOrObject;
private readonly httpAgent?;
readonly implicit: boolean;
private googleAuth;
private authClient;
/**
* Creates a new ImpersonatedServiceAccountCredential from the given parameters.
*
* @param impersonatedServiceAccountPathOrObject - Impersonated Service account json object or
* path to a service account json file.
* @param httpAgent - Optional http.Agent to use when calling the remote token server.
* @param implicit - An optional boolean indicating whether this credential was implicitly
* discovered from the environment, as opposed to being explicitly specified by the developer.
*
* @constructor
*/
constructor(impersonatedServiceAccountPathOrObject: string | object, httpAgent?: Agent | undefined, implicit?: boolean);
private getGoogleAuth;
getAccessToken(): Promise<GoogleOAuthAccessToken>;
}
/**
* Checks if the given credential was loaded via the application default credentials mechanism.
*
* @param credential - The credential instance to check.
*/
export declare function isApplicationDefault(credential?: Credential): boolean;
export declare function getApplicationDefault(httpAgent?: Agent): Credential;

View File

@@ -0,0 +1,418 @@
/*! firebase-admin v13.5.0 */
"use strict";
/*!
* @license
* Copyright 2020 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImpersonatedServiceAccountCredential = exports.RefreshTokenCredential = exports.ServiceAccountCredential = exports.ApplicationDefaultCredential = void 0;
exports.isApplicationDefault = isApplicationDefault;
exports.getApplicationDefault = getApplicationDefault;
const fs = require("fs");
const google_auth_library_1 = require("google-auth-library");
const error_1 = require("../utils/error");
const util = require("../utils/validator");
const SCOPES = [
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/firebase.database',
'https://www.googleapis.com/auth/firebase.messaging',
'https://www.googleapis.com/auth/identitytoolkit',
'https://www.googleapis.com/auth/userinfo.email',
];
/**
* Implementation of ADC that uses google-auth-library-nodejs.
*/
class ApplicationDefaultCredential {
constructor(httpAgent) {
this.googleAuth = new google_auth_library_1.GoogleAuth({
scopes: SCOPES,
clientOptions: {
transporterOptions: {
agent: httpAgent,
},
},
});
}
async getAccessToken() {
if (!this.authClient) {
this.authClient = await this.googleAuth.getClient();
}
await this.authClient.getAccessToken();
const credentials = this.authClient.credentials;
this.quotaProjectId = this.authClient.quotaProjectId;
return populateCredential(credentials);
}
async getProjectId() {
if (!this.projectId) {
this.projectId = await this.googleAuth.getProjectId();
}
return Promise.resolve(this.projectId);
}
getQuotaProjectId() {
if (!this.quotaProjectId) {
this.quotaProjectId = this.authClient?.quotaProjectId;
}
return this.quotaProjectId;
}
async isComputeEngineCredential() {
if (!this.authClient) {
this.authClient = await this.googleAuth.getClient();
}
return Promise.resolve(this.authClient instanceof google_auth_library_1.Compute);
}
/**
* getIDToken returns a OIDC token from the compute metadata service
* that can be used to make authenticated calls to audience
* @param audience the URL the returned ID token will be used to call.
*/
async getIDToken(audience) {
if (await this.isComputeEngineCredential()) {
return this.authClient.fetchIdToken(audience);
}
else {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Credentials type should be Compute Engine Credentials.');
}
}
async getServiceAccountEmail() {
if (this.accountId) {
return Promise.resolve(this.accountId);
}
const { client_email: clientEmail } = await this.googleAuth.getCredentials();
this.accountId = clientEmail ?? '';
return Promise.resolve(this.accountId);
}
}
exports.ApplicationDefaultCredential = ApplicationDefaultCredential;
/**
* Implementation of Credential that uses a service account.
*/
class ServiceAccountCredential {
/**
* Creates a new ServiceAccountCredential from the given parameters.
*
* @param serviceAccountPathOrObject - Service account json object or path to a service account json file.
* @param httpAgent - Optional http.Agent to use when calling the remote token server.
* @param implicit - An optional boolean indicating whether this credential was implicitly discovered from the
* environment, as opposed to being explicitly specified by the developer.
*
* @constructor
*/
constructor(serviceAccountPathOrObject, httpAgent, implicit = false) {
this.serviceAccountPathOrObject = serviceAccountPathOrObject;
this.httpAgent = httpAgent;
this.implicit = implicit;
const serviceAccount = (typeof serviceAccountPathOrObject === 'string') ?
ServiceAccount.fromPath(serviceAccountPathOrObject)
: new ServiceAccount(serviceAccountPathOrObject);
this.projectId = serviceAccount.projectId;
this.privateKey = serviceAccount.privateKey;
this.clientEmail = serviceAccount.clientEmail;
}
getGoogleAuth() {
if (this.googleAuth) {
return this.googleAuth;
}
const { auth, client } = populateGoogleAuth(this.serviceAccountPathOrObject, this.httpAgent);
this.googleAuth = auth;
this.authClient = client;
return this.googleAuth;
}
async getAccessToken() {
const googleAuth = this.getGoogleAuth();
if (this.authClient === undefined) {
this.authClient = await googleAuth.getClient();
}
await this.authClient.getAccessToken();
const credentials = this.authClient.credentials;
return populateCredential(credentials);
}
}
exports.ServiceAccountCredential = ServiceAccountCredential;
/**
* A struct containing the properties necessary to use service account JSON credentials.
*/
class ServiceAccount {
static fromPath(filePath) {
try {
return new ServiceAccount(JSON.parse(fs.readFileSync(filePath, 'utf8')));
}
catch (error) {
// Throw a nicely formed error message if the file contents cannot be parsed
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse service account json file: ' + error);
}
}
constructor(json) {
if (!util.isNonNullObject(json)) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Service account must be an object.');
}
copyAttr(this, json, 'projectId', 'project_id');
copyAttr(this, json, 'privateKey', 'private_key');
copyAttr(this, json, 'clientEmail', 'client_email');
let errorMessage;
if (!util.isNonEmptyString(this.projectId)) {
errorMessage = 'Service account object must contain a string "project_id" property.';
}
else if (!util.isNonEmptyString(this.privateKey)) {
errorMessage = 'Service account object must contain a string "private_key" property.';
}
else if (!util.isNonEmptyString(this.clientEmail)) {
errorMessage = 'Service account object must contain a string "client_email" property.';
}
if (typeof errorMessage !== 'undefined') {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, errorMessage);
}
// eslint-disable-next-line @typescript-eslint/no-var-requires
const forge = require('node-forge');
try {
forge.pki.privateKeyFromPem(this.privateKey);
}
catch (error) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse private key: ' + error);
}
}
}
/**
* Implementation of Credential that gets access tokens from refresh tokens.
*/
class RefreshTokenCredential {
/**
* Creates a new RefreshTokenCredential from the given parameters.
*
* @param refreshTokenPathOrObject - Refresh token json object or path to a refresh token
* (user credentials) json file.
* @param httpAgent - Optional http.Agent to use when calling the remote token server.
* @param implicit - An optinal boolean indicating whether this credential was implicitly
* discovered from the environment, as opposed to being explicitly specified by the developer.
*
* @constructor
*/
constructor(refreshTokenPathOrObject, httpAgent, implicit = false) {
this.refreshTokenPathOrObject = refreshTokenPathOrObject;
this.httpAgent = httpAgent;
this.implicit = implicit;
(typeof refreshTokenPathOrObject === 'string') ?
RefreshToken.validateFromPath(refreshTokenPathOrObject)
: RefreshToken.validateFromJSON(refreshTokenPathOrObject);
}
getGoogleAuth() {
if (this.googleAuth) {
return this.googleAuth;
}
const { auth, client } = populateGoogleAuth(this.refreshTokenPathOrObject, this.httpAgent);
this.googleAuth = auth;
this.authClient = client;
return this.googleAuth;
}
async getAccessToken() {
const googleAuth = this.getGoogleAuth();
if (this.authClient === undefined) {
this.authClient = await googleAuth.getClient();
}
await this.authClient.getAccessToken();
const credentials = this.authClient.credentials;
return populateCredential(credentials);
}
}
exports.RefreshTokenCredential = RefreshTokenCredential;
class RefreshToken {
/*
* Tries to load a RefreshToken from a path. Throws if the path doesn't exist or the
* data at the path is invalid.
*/
static validateFromPath(filePath) {
try {
RefreshToken.validateFromJSON(JSON.parse(fs.readFileSync(filePath, 'utf8')));
}
catch (error) {
// Throw a nicely formed error message if the file contents cannot be parsed
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse refresh token file: ' + error);
}
}
static validateFromJSON(json) {
const creds = { clientId: '', clientSecret: '', refreshToken: '', type: '' };
copyAttr(creds, json, 'clientId', 'client_id');
copyAttr(creds, json, 'clientSecret', 'client_secret');
copyAttr(creds, json, 'refreshToken', 'refresh_token');
copyAttr(creds, json, 'type', 'type');
let errorMessage;
if (!util.isNonEmptyString(creds.clientId)) {
errorMessage = 'Refresh token must contain a "client_id" property.';
}
else if (!util.isNonEmptyString(creds.clientSecret)) {
errorMessage = 'Refresh token must contain a "client_secret" property.';
}
else if (!util.isNonEmptyString(creds.refreshToken)) {
errorMessage = 'Refresh token must contain a "refresh_token" property.';
}
else if (!util.isNonEmptyString(creds.type)) {
errorMessage = 'Refresh token must contain a "type" property.';
}
if (typeof errorMessage !== 'undefined') {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, errorMessage);
}
}
}
/**
* Implementation of Credential that uses impersonated service account.
*/
class ImpersonatedServiceAccountCredential {
/**
* Creates a new ImpersonatedServiceAccountCredential from the given parameters.
*
* @param impersonatedServiceAccountPathOrObject - Impersonated Service account json object or
* path to a service account json file.
* @param httpAgent - Optional http.Agent to use when calling the remote token server.
* @param implicit - An optional boolean indicating whether this credential was implicitly
* discovered from the environment, as opposed to being explicitly specified by the developer.
*
* @constructor
*/
constructor(impersonatedServiceAccountPathOrObject, httpAgent, implicit = false) {
this.impersonatedServiceAccountPathOrObject = impersonatedServiceAccountPathOrObject;
this.httpAgent = httpAgent;
this.implicit = implicit;
(typeof impersonatedServiceAccountPathOrObject === 'string') ?
ImpersonatedServiceAccount.validateFromPath(impersonatedServiceAccountPathOrObject)
: ImpersonatedServiceAccount.validateFromJSON(impersonatedServiceAccountPathOrObject);
}
getGoogleAuth() {
if (this.googleAuth) {
return this.googleAuth;
}
const { auth, client } = populateGoogleAuth(this.impersonatedServiceAccountPathOrObject, this.httpAgent);
this.googleAuth = auth;
this.authClient = client;
return this.googleAuth;
}
async getAccessToken() {
const googleAuth = this.getGoogleAuth();
if (this.authClient === undefined) {
this.authClient = await googleAuth.getClient();
}
await this.authClient.getAccessToken();
const credentials = this.authClient.credentials;
return populateCredential(credentials);
}
}
exports.ImpersonatedServiceAccountCredential = ImpersonatedServiceAccountCredential;
/**
* A helper class to validate the properties necessary to use impersonated service account credentials.
*/
class ImpersonatedServiceAccount {
/*
* Tries to load a ImpersonatedServiceAccount from a path. Throws if the path doesn't exist or the
* data at the path is invalid.
*/
static validateFromPath(filePath) {
try {
ImpersonatedServiceAccount.validateFromJSON(JSON.parse(fs.readFileSync(filePath, 'utf8')));
}
catch (error) {
// Throw a nicely formed error message if the file contents cannot be parsed
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse impersonated service account file: ' + error);
}
}
static validateFromJSON(json) {
const { client_id: clientId, client_secret: clientSecret, refresh_token: refreshToken, type } = json['source_credentials'];
let errorMessage;
if (!util.isNonEmptyString(clientId)) {
errorMessage = 'Impersonated Service Account must contain a "source_credentials.client_id" property.';
}
else if (!util.isNonEmptyString(clientSecret)) {
errorMessage = 'Impersonated Service Account must contain a "source_credentials.client_secret" property.';
}
else if (!util.isNonEmptyString(refreshToken)) {
errorMessage = 'Impersonated Service Account must contain a "source_credentials.refresh_token" property.';
}
else if (!util.isNonEmptyString(type)) {
errorMessage = 'Impersonated Service Account must contain a "source_credentials.type" property.';
}
if (typeof errorMessage !== 'undefined') {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, errorMessage);
}
}
}
/**
* Checks if the given credential was loaded via the application default credentials mechanism.
*
* @param credential - The credential instance to check.
*/
function isApplicationDefault(credential) {
return credential instanceof ApplicationDefaultCredential ||
(credential instanceof RefreshTokenCredential && credential.implicit);
}
function getApplicationDefault(httpAgent) {
return new ApplicationDefaultCredential(httpAgent);
}
/**
* Copies the specified property from one object to another.
*
* If no property exists by the given "key", looks for a property identified by "alt", and copies it instead.
* This can be used to implement behaviors such as "copy property myKey or my_key".
*
* @param to - Target object to copy the property into.
* @param from - Source object to copy the property from.
* @param key - Name of the property to copy.
* @param alt - Alternative name of the property to copy.
*/
function copyAttr(to, from, key, alt) {
const tmp = from[key] || from[alt];
if (typeof tmp !== 'undefined') {
to[key] = tmp;
}
}
/**
* Populate google-auth-library GoogleAuth credentials type.
*/
function populateGoogleAuth(keyFile, httpAgent) {
let client;
const auth = new google_auth_library_1.GoogleAuth({
scopes: SCOPES,
clientOptions: {
transporterOptions: {
agent: httpAgent,
},
},
keyFile: (typeof keyFile === 'string') ? keyFile : undefined,
});
if (typeof keyFile === 'object') {
if (!util.isNonNullObject(keyFile)) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Service account must be an object.');
}
copyAttr(keyFile, keyFile, 'project_id', 'projectId');
copyAttr(keyFile, keyFile, 'private_key', 'privateKey');
copyAttr(keyFile, keyFile, 'client_email', 'clientEmail');
client = auth.fromJSON(keyFile);
}
return { auth, client };
}
/**
* Populate GoogleOAuthAccessToken credentials from google-auth-library Credentials type.
*/
function populateCredential(credentials) {
const accessToken = credentials?.access_token;
const expiryDate = credentials?.expiry_date;
if (typeof accessToken !== 'string')
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse Google auth credential: access_token must be a non empty string.');
if (typeof expiryDate !== 'number')
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, 'Failed to parse Google auth credential: Invalid expiry_date.');
return {
...credentials,
access_token: accessToken,
// inverse operation of following
// https://github.com/googleapis/google-auth-library-nodejs/blob/5ed910513451c82e2551777a3e2212964799ef8e/src/auth/baseexternalclient.ts#L446-L446
expires_in: Math.floor((expiryDate - new Date().getTime()) / 1000),
};
}

View File

@@ -0,0 +1,45 @@
/*! firebase-admin v13.5.0 */
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export interface ServiceAccount {
projectId?: string;
clientEmail?: string;
privateKey?: string;
}
/**
* Interface for Google OAuth 2.0 access tokens.
*/
export interface GoogleOAuthAccessToken {
access_token: string;
expires_in: number;
}
/**
* Interface that provides Google OAuth2 access tokens used to authenticate
* with Firebase services.
*
* In most cases, you will not need to implement this yourself and can instead
* use the default implementations provided by the `firebase-admin/app` module.
*/
export interface Credential {
/**
* Returns a Google OAuth2 access token object used to authenticate with
* Firebase services.
*
* @returns A Google OAuth2 access token object.
*/
getAccessToken(): Promise<GoogleOAuthAccessToken>;
}

View File

@@ -0,0 +1,19 @@
/*! firebase-admin v13.5.0 */
"use strict";
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,53 @@
/*! firebase-admin v13.5.0 */
/*!
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Credential } from './credential';
/**
* Type representing a Firebase OAuth access token (derived from a Google OAuth2 access token) which
* can be used to authenticate to Firebase services such as the Realtime Database and Auth.
*/
export interface FirebaseAccessToken {
accessToken: string;
expirationTime: number;
}
/**
* Internals of a FirebaseApp instance.
*/
export declare class FirebaseAppInternals {
private credential_;
private cachedToken_;
private promiseToCachedToken_;
private tokenListeners_;
private isRefreshing;
constructor(credential_: Credential);
getToken(forceRefresh?: boolean): Promise<FirebaseAccessToken>;
getCachedToken(): FirebaseAccessToken | null;
private refreshToken;
private shouldRefresh;
/**
* Adds a listener that is called each time a token changes.
*
* @param listener - The listener that will be called with each new token.
*/
addAuthTokenListener(listener: (token: string) => void): void;
/**
* Removes a token listener.
*
* @param listener - The listener to remove.
*/
removeAuthTokenListener(listener: (token: string) => void): void;
}

View File

@@ -0,0 +1,234 @@
/*! firebase-admin v13.5.0 */
"use strict";
/*!
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.FirebaseApp = exports.FirebaseAppInternals = void 0;
const credential_internal_1 = require("./credential-internal");
const validator = require("../utils/validator");
const deep_copy_1 = require("../utils/deep-copy");
const error_1 = require("../utils/error");
const TOKEN_EXPIRY_THRESHOLD_MILLIS = 5 * 60 * 1000;
/**
* Internals of a FirebaseApp instance.
*/
class FirebaseAppInternals {
// eslint-disable-next-line @typescript-eslint/naming-convention
constructor(credential_) {
this.credential_ = credential_;
this.tokenListeners_ = [];
this.isRefreshing = false;
}
getToken(forceRefresh = false) {
if (forceRefresh || this.shouldRefresh()) {
this.promiseToCachedToken_ = this.refreshToken();
}
return this.promiseToCachedToken_;
}
getCachedToken() {
return this.cachedToken_ || null;
}
refreshToken() {
this.isRefreshing = true;
return Promise.resolve(this.credential_.getAccessToken())
.then((result) => {
// Since the developer can provide the credential implementation, we want to weakly verify
// the return type until the type is properly exported.
if (!validator.isNonNullObject(result) ||
typeof result.expires_in !== 'number' ||
typeof result.access_token !== 'string') {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, `Invalid access token generated: "${JSON.stringify(result)}". Valid access ` +
'tokens must be an object with the "expires_in" (number) and "access_token" ' +
'(string) properties.');
}
const token = {
accessToken: result.access_token,
expirationTime: Date.now() + (result.expires_in * 1000),
};
if (!this.cachedToken_
|| this.cachedToken_.accessToken !== token.accessToken
|| this.cachedToken_.expirationTime !== token.expirationTime) {
// Update the cache before firing listeners. Listeners may directly query the
// cached token state.
this.cachedToken_ = token;
this.tokenListeners_.forEach((listener) => {
listener(token.accessToken);
});
}
return token;
})
.catch((error) => {
let errorMessage = (typeof error === 'string') ? error : error.message;
errorMessage = 'Credential implementation provided to initializeApp() via the ' +
'"credential" property failed to fetch a valid Google OAuth2 access token with the ' +
`following error: "${errorMessage}".`;
if (errorMessage.indexOf('invalid_grant') !== -1) {
errorMessage += ' There are two likely causes: (1) your server time is not properly ' +
'synced or (2) your certificate key file has been revoked. To solve (1), re-sync the ' +
'time on your server. To solve (2), make sure the key ID for your key file is still ' +
'present at https://console.firebase.google.com/iam-admin/serviceaccounts/project. If ' +
'not, generate a new key file at ' +
'https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk.';
}
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, errorMessage);
})
.finally(() => {
this.isRefreshing = false;
});
}
shouldRefresh() {
return (!this.cachedToken_ || (this.cachedToken_.expirationTime - Date.now()) <= TOKEN_EXPIRY_THRESHOLD_MILLIS)
&& !this.isRefreshing;
}
/**
* Adds a listener that is called each time a token changes.
*
* @param listener - The listener that will be called with each new token.
*/
addAuthTokenListener(listener) {
this.tokenListeners_.push(listener);
if (this.cachedToken_) {
listener(this.cachedToken_.accessToken);
}
}
/**
* Removes a token listener.
*
* @param listener - The listener to remove.
*/
removeAuthTokenListener(listener) {
this.tokenListeners_ = this.tokenListeners_.filter((other) => other !== listener);
}
}
exports.FirebaseAppInternals = FirebaseAppInternals;
/**
* Global context object for a collection of services using a shared authentication state.
*
* @internal
*/
class FirebaseApp {
constructor(options, name, autoInit = false, appStore) {
this.appStore = appStore;
this.services_ = {};
this.isDeleted_ = false;
this.autoInit_ = false;
this.customCredential_ = true;
this.name_ = name;
this.options_ = (0, deep_copy_1.deepCopy)(options);
this.autoInit_ = autoInit;
if (!validator.isNonNullObject(this.options_)) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, 'Invalid Firebase app options passed as the first argument to initializeApp() for the ' +
`app named "${this.name_}". Options must be a non-null object.`);
}
const hasCredential = ('credential' in this.options_);
if (!hasCredential) {
this.customCredential_ = false;
this.options_.credential = (0, credential_internal_1.getApplicationDefault)(this.options_.httpAgent);
}
const credential = this.options_.credential;
if (typeof credential !== 'object' || credential === null || typeof credential.getAccessToken !== 'function') {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, 'Invalid Firebase app options passed as the first argument to initializeApp() for the ' +
`app named "${this.name_}". The "credential" property must be an object which implements ` +
'the Credential interface.');
}
this.INTERNAL = new FirebaseAppInternals(credential);
}
/**
* Returns the name of the FirebaseApp instance.
*
* @returns The name of the FirebaseApp instance.
*/
get name() {
this.checkDestroyed_();
return this.name_;
}
/**
* Returns the options for the FirebaseApp instance.
*
* @returns The options for the FirebaseApp instance.
*/
get options() {
this.checkDestroyed_();
return (0, deep_copy_1.deepCopy)(this.options_);
}
/**
* @internal
*/
getOrInitService(name, init) {
return this.ensureService_(name, () => init(this));
}
/**
* Returns `true` if this app was initialized with auto-initialization.
*
* @internal
*/
autoInit() {
return this.autoInit_;
}
/**
* Returns `true` if the `FirebaseApp` instance was initialized with a custom
* `Credential`.
*
* @internal
*/
customCredential() {
return this.customCredential_;
}
/**
* Deletes the FirebaseApp instance.
*
* @returns An empty Promise fulfilled once the FirebaseApp instance is deleted.
*/
delete() {
this.checkDestroyed_();
// Also remove the instance from the AppStore. This is needed to support the existing
// app.delete() use case. In the future we can remove this API, and deleteApp() will
// become the only way to tear down an App.
this.appStore?.removeApp(this.name);
return Promise.all(Object.keys(this.services_).map((serviceName) => {
const service = this.services_[serviceName];
if (isStateful(service)) {
return service.delete();
}
return Promise.resolve();
})).then(() => {
this.services_ = {};
this.isDeleted_ = true;
});
}
// eslint-disable-next-line @typescript-eslint/naming-convention
ensureService_(serviceName, initializer) {
this.checkDestroyed_();
if (!(serviceName in this.services_)) {
this.services_[serviceName] = initializer();
}
return this.services_[serviceName];
}
/**
* Throws an Error if the FirebaseApp instance has already been deleted.
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
checkDestroyed_() {
if (this.isDeleted_) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.APP_DELETED, `Firebase app named "${this.name_}" has already been deleted.`);
}
}
}
exports.FirebaseApp = FirebaseApp;
function isStateful(service) {
return typeof service.delete === 'function';
}

View File

@@ -0,0 +1,163 @@
/*! firebase-admin v13.5.0 */
/*!
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AppStore } from './lifecycle';
import { app, appCheck, auth, messaging, machineLearning, storage, firestore, database, instanceId, installations, projectManagement, securityRules, remoteConfig, AppOptions } from '../firebase-namespace-api';
import { cert, refreshToken, applicationDefault } from './credential-factory';
import App = app.App;
import AppCheck = appCheck.AppCheck;
import Auth = auth.Auth;
import Database = database.Database;
import Firestore = firestore.Firestore;
import Installations = installations.Installations;
import InstanceId = instanceId.InstanceId;
import MachineLearning = machineLearning.MachineLearning;
import Messaging = messaging.Messaging;
import ProjectManagement = projectManagement.ProjectManagement;
import RemoteConfig = remoteConfig.RemoteConfig;
import SecurityRules = securityRules.SecurityRules;
import Storage = storage.Storage;
export interface FirebaseServiceNamespace<T> {
(app?: App): T;
[key: string]: any;
}
/**
* Internals of a FirebaseNamespace instance.
*/
export declare class FirebaseNamespaceInternals {
private readonly appStore;
constructor(appStore: AppStore);
/**
* Initializes the App instance.
*
* @param options - Optional options for the App instance. If none present will try to initialize
* from the FIREBASE_CONFIG environment variable. If the environment variable contains a string
* that starts with '{' it will be parsed as JSON, otherwise it will be assumed to be pointing
* to a file.
* @param appName - Optional name of the FirebaseApp instance.
*
* @returns A new App instance.
*/
initializeApp(options?: AppOptions, appName?: string): App;
/**
* Returns the App instance with the provided name (or the default App instance
* if no name is provided).
*
* @param appName - Optional name of the FirebaseApp instance to return.
* @returns The App instance which has the provided name.
*/
app(appName?: string): App;
get apps(): App[];
}
/**
* Global Firebase context object.
*/
export declare class FirebaseNamespace {
__esModule: boolean;
credential: {
cert: typeof cert;
refreshToken: typeof refreshToken;
applicationDefault: typeof applicationDefault;
};
SDK_VERSION: string;
INTERNAL: FirebaseNamespaceInternals;
Promise: any;
constructor(appStore?: AppStore);
/**
* Gets the `Auth` service namespace. The returned namespace can be used to get the
* `Auth` service for the default app or an explicitly specified app.
*/
get auth(): FirebaseServiceNamespace<Auth>;
/**
* Gets the `Database` service namespace. The returned namespace can be used to get the
* `Database` service for the default app or an explicitly specified app.
*/
get database(): FirebaseServiceNamespace<Database>;
/**
* Gets the `Messaging` service namespace. The returned namespace can be used to get the
* `Messaging` service for the default app or an explicitly specified app.
*/
get messaging(): FirebaseServiceNamespace<Messaging>;
/**
* Gets the `Storage` service namespace. The returned namespace can be used to get the
* `Storage` service for the default app or an explicitly specified app.
*/
get storage(): FirebaseServiceNamespace<Storage>;
/**
* Gets the `Firestore` service namespace. The returned namespace can be used to get the
* `Firestore` service for the default app or an explicitly specified app.
*/
get firestore(): FirebaseServiceNamespace<Firestore>;
/**
* Gets the `MachineLearning` service namespace. The returned namespace can be
* used to get the `MachineLearning` service for the default app or an
* explicityly specified app.
*/
get machineLearning(): FirebaseServiceNamespace<MachineLearning>;
/**
* Gets the `Installations` service namespace. The returned namespace can be used to get the
* `Installations` service for the default app or an explicitly specified app.
*/
get installations(): FirebaseServiceNamespace<Installations>;
/**
* Gets the `InstanceId` service namespace. The returned namespace can be used to get the
* `Instance` service for the default app or an explicitly specified app.
*/
get instanceId(): FirebaseServiceNamespace<InstanceId>;
/**
* Gets the `ProjectManagement` service namespace. The returned namespace can be used to get the
* `ProjectManagement` service for the default app or an explicitly specified app.
*/
get projectManagement(): FirebaseServiceNamespace<ProjectManagement>;
/**
* Gets the `SecurityRules` service namespace. The returned namespace can be used to get the
* `SecurityRules` service for the default app or an explicitly specified app.
*/
get securityRules(): FirebaseServiceNamespace<SecurityRules>;
/**
* Gets the `RemoteConfig` service namespace. The returned namespace can be used to get the
* `RemoteConfig` service for the default app or an explicitly specified app.
*/
get remoteConfig(): FirebaseServiceNamespace<RemoteConfig>;
/**
* Gets the `AppCheck` service namespace. The returned namespace can be used to get the
* `AppCheck` service for the default app or an explicitly specified app.
*/
get appCheck(): FirebaseServiceNamespace<AppCheck>;
/**
* Initializes the FirebaseApp instance.
*
* @param options - Optional options for the FirebaseApp instance.
* If none present will try to initialize from the FIREBASE_CONFIG environment variable.
* If the environment variable contains a string that starts with '{' it will be parsed as JSON,
* otherwise it will be assumed to be pointing to a file.
* @param appName - Optional name of the FirebaseApp instance.
*
* @returns A new FirebaseApp instance.
*/
initializeApp(options?: AppOptions, appName?: string): App;
/**
* Returns the FirebaseApp instance with the provided name (or the default FirebaseApp instance
* if no name is provided).
*
* @param appName - Optional name of the FirebaseApp instance to return.
* @returns The FirebaseApp instance which has the provided name.
*/
app(appName?: string): App;
get apps(): App[];
private ensureApp;
}

View File

@@ -0,0 +1,335 @@
/*! firebase-admin v13.5.0 */
"use strict";
/*!
* @license
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultNamespace = exports.FirebaseNamespace = exports.FirebaseNamespaceInternals = void 0;
const lifecycle_1 = require("./lifecycle");
const credential_factory_1 = require("./credential-factory");
const index_1 = require("../utils/index");
/**
* Internals of a FirebaseNamespace instance.
*/
class FirebaseNamespaceInternals {
constructor(appStore) {
this.appStore = appStore;
}
/**
* Initializes the App instance.
*
* @param options - Optional options for the App instance. If none present will try to initialize
* from the FIREBASE_CONFIG environment variable. If the environment variable contains a string
* that starts with '{' it will be parsed as JSON, otherwise it will be assumed to be pointing
* to a file.
* @param appName - Optional name of the FirebaseApp instance.
*
* @returns A new App instance.
*/
initializeApp(options, appName) {
const app = this.appStore.initializeApp(options, appName);
return extendApp(app);
}
/**
* Returns the App instance with the provided name (or the default App instance
* if no name is provided).
*
* @param appName - Optional name of the FirebaseApp instance to return.
* @returns The App instance which has the provided name.
*/
app(appName) {
const app = this.appStore.getApp(appName);
return extendApp(app);
}
/*
* Returns an array of all the non-deleted App instances.
*/
get apps() {
return this.appStore.getApps().map((app) => extendApp(app));
}
}
exports.FirebaseNamespaceInternals = FirebaseNamespaceInternals;
const firebaseCredential = {
cert: credential_factory_1.cert, refreshToken: credential_factory_1.refreshToken, applicationDefault: credential_factory_1.applicationDefault
};
/**
* Global Firebase context object.
*/
class FirebaseNamespace {
/* tslint:enable */
constructor(appStore) {
// Hack to prevent Babel from modifying the object returned as the default admin namespace.
/* tslint:disable:variable-name */
this.__esModule = true;
/* tslint:enable:variable-name */
this.credential = firebaseCredential;
this.SDK_VERSION = (0, index_1.getSdkVersion)();
/* tslint:disable */
// TODO(jwenger): Database is the only consumer of firebase.Promise. We should update it to use
// use the native Promise and then remove this.
this.Promise = Promise;
this.INTERNAL = new FirebaseNamespaceInternals(appStore ?? new lifecycle_1.AppStore());
}
/**
* Gets the `Auth` service namespace. The returned namespace can be used to get the
* `Auth` service for the default app or an explicitly specified app.
*/
get auth() {
const fn = (app) => {
return this.ensureApp(app).auth();
};
const auth = require('../auth/auth').Auth;
return Object.assign(fn, { Auth: auth });
}
/**
* Gets the `Database` service namespace. The returned namespace can be used to get the
* `Database` service for the default app or an explicitly specified app.
*/
get database() {
const fn = (app) => {
return this.ensureApp(app).database();
};
// eslint-disable-next-line @typescript-eslint/no-var-requires
return Object.assign(fn, require('@firebase/database-compat/standalone'));
}
/**
* Gets the `Messaging` service namespace. The returned namespace can be used to get the
* `Messaging` service for the default app or an explicitly specified app.
*/
get messaging() {
const fn = (app) => {
return this.ensureApp(app).messaging();
};
const messaging = require('../messaging/messaging').Messaging;
return Object.assign(fn, { Messaging: messaging });
}
/**
* Gets the `Storage` service namespace. The returned namespace can be used to get the
* `Storage` service for the default app or an explicitly specified app.
*/
get storage() {
const fn = (app) => {
return this.ensureApp(app).storage();
};
const storage = require('../storage/storage').Storage;
return Object.assign(fn, { Storage: storage });
}
/**
* Gets the `Firestore` service namespace. The returned namespace can be used to get the
* `Firestore` service for the default app or an explicitly specified app.
*/
get firestore() {
let fn = (app) => {
return this.ensureApp(app).firestore();
};
// eslint-disable-next-line @typescript-eslint/no-var-requires
const firestore = require('@google-cloud/firestore');
fn = Object.assign(fn, firestore.Firestore);
// `v1beta1` and `v1` are lazy-loaded in the Firestore SDK. We use the same trick here
// to avoid triggering this lazy-loading upon initialization.
Object.defineProperty(fn, 'v1beta1', {
get: () => {
return firestore.v1beta1;
},
});
Object.defineProperty(fn, 'v1', {
get: () => {
return firestore.v1;
},
});
return fn;
}
/**
* Gets the `MachineLearning` service namespace. The returned namespace can be
* used to get the `MachineLearning` service for the default app or an
* explicityly specified app.
*/
get machineLearning() {
const fn = (app) => {
return this.ensureApp(app).machineLearning();
};
const machineLearning = require('../machine-learning/machine-learning').MachineLearning;
return Object.assign(fn, { MachineLearning: machineLearning });
}
/**
* Gets the `Installations` service namespace. The returned namespace can be used to get the
* `Installations` service for the default app or an explicitly specified app.
*/
get installations() {
const fn = (app) => {
return this.ensureApp(app).installations();
};
const installations = require('../installations/installations').Installations;
return Object.assign(fn, { Installations: installations });
}
/**
* Gets the `InstanceId` service namespace. The returned namespace can be used to get the
* `Instance` service for the default app or an explicitly specified app.
*/
get instanceId() {
const fn = (app) => {
return this.ensureApp(app).instanceId();
};
const instanceId = require('../instance-id/instance-id').InstanceId;
return Object.assign(fn, { InstanceId: instanceId });
}
/**
* Gets the `ProjectManagement` service namespace. The returned namespace can be used to get the
* `ProjectManagement` service for the default app or an explicitly specified app.
*/
get projectManagement() {
const fn = (app) => {
return this.ensureApp(app).projectManagement();
};
const projectManagement = require('../project-management/project-management').ProjectManagement;
return Object.assign(fn, { ProjectManagement: projectManagement });
}
/**
* Gets the `SecurityRules` service namespace. The returned namespace can be used to get the
* `SecurityRules` service for the default app or an explicitly specified app.
*/
get securityRules() {
const fn = (app) => {
return this.ensureApp(app).securityRules();
};
const securityRules = require('../security-rules/security-rules').SecurityRules;
return Object.assign(fn, { SecurityRules: securityRules });
}
/**
* Gets the `RemoteConfig` service namespace. The returned namespace can be used to get the
* `RemoteConfig` service for the default app or an explicitly specified app.
*/
get remoteConfig() {
const fn = (app) => {
return this.ensureApp(app).remoteConfig();
};
const remoteConfig = require('../remote-config/remote-config').RemoteConfig;
return Object.assign(fn, { RemoteConfig: remoteConfig });
}
/**
* Gets the `AppCheck` service namespace. The returned namespace can be used to get the
* `AppCheck` service for the default app or an explicitly specified app.
*/
get appCheck() {
const fn = (app) => {
return this.ensureApp(app).appCheck();
};
const appCheck = require('../app-check/app-check').AppCheck;
return Object.assign(fn, { AppCheck: appCheck });
}
// TODO: Change the return types to app.App in the following methods.
/**
* Initializes the FirebaseApp instance.
*
* @param options - Optional options for the FirebaseApp instance.
* If none present will try to initialize from the FIREBASE_CONFIG environment variable.
* If the environment variable contains a string that starts with '{' it will be parsed as JSON,
* otherwise it will be assumed to be pointing to a file.
* @param appName - Optional name of the FirebaseApp instance.
*
* @returns A new FirebaseApp instance.
*/
initializeApp(options, appName) {
return this.INTERNAL.initializeApp(options, appName);
}
/**
* Returns the FirebaseApp instance with the provided name (or the default FirebaseApp instance
* if no name is provided).
*
* @param appName - Optional name of the FirebaseApp instance to return.
* @returns The FirebaseApp instance which has the provided name.
*/
app(appName) {
return this.INTERNAL.app(appName);
}
/*
* Returns an array of all the non-deleted FirebaseApp instances.
*/
get apps() {
return this.INTERNAL.apps;
}
ensureApp(app) {
if (typeof app === 'undefined') {
app = this.app();
}
return app;
}
}
exports.FirebaseNamespace = FirebaseNamespace;
/**
* In order to maintain backward compatibility, we instantiate a default namespace instance in
* this module, and delegate all app lifecycle operations to it. In a future implementation where
* the old admin namespace is no longer supported, we should remove this.
*
* @internal
*/
exports.defaultNamespace = new FirebaseNamespace(lifecycle_1.defaultAppStore);
function extendApp(app) {
const result = app;
if (result.__extended) {
return result;
}
result.auth = () => {
const fn = require('../auth/index').getAuth;
return fn(app);
};
result.appCheck = () => {
const fn = require('../app-check/index').getAppCheck;
return fn(app);
};
result.database = (url) => {
const fn = require('../database/index').getDatabaseWithUrl;
return fn(url, app);
};
result.messaging = () => {
const fn = require('../messaging/index').getMessaging;
return fn(app);
};
result.storage = () => {
const fn = require('../storage/index').getStorage;
return fn(app);
};
result.firestore = () => {
const fn = require('../firestore/index').getFirestore;
return fn(app);
};
result.instanceId = () => {
const fn = require('../instance-id/index').getInstanceId;
return fn(app);
};
result.installations = () => {
const fn = require('../installations/index').getInstallations;
return fn(app);
};
result.machineLearning = () => {
const fn = require('../machine-learning/index').getMachineLearning;
return fn(app);
};
result.projectManagement = () => {
const fn = require('../project-management/index').getProjectManagement;
return fn(app);
};
result.securityRules = () => {
const fn = require('../security-rules/index').getSecurityRules;
return fn(app);
};
result.remoteConfig = () => {
const fn = require('../remote-config/index').getRemoteConfig;
return fn(app);
};
result.__extended = true;
return result;
}

28
server/node_modules/firebase-admin/lib/app/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,28 @@
/*! firebase-admin v13.5.0 */
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Firebase App and SDK initialization.
*
* @packageDocumentation
*/
export { App, AppOptions, FirebaseArrayIndexError, FirebaseError } from './core';
export { initializeApp, getApp, getApps, deleteApp } from './lifecycle';
export { Credential, ServiceAccount, GoogleOAuthAccessToken } from './credential';
export { applicationDefault, cert, refreshToken } from './credential-factory';
export { FirebaseAppError, AppErrorCodes } from '../utils/error';
export declare const SDK_VERSION: string;

34
server/node_modules/firebase-admin/lib/app/index.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
/*! firebase-admin v13.5.0 */
"use strict";
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SDK_VERSION = exports.AppErrorCodes = exports.FirebaseAppError = exports.refreshToken = exports.cert = exports.applicationDefault = exports.deleteApp = exports.getApps = exports.getApp = exports.initializeApp = void 0;
const utils_1 = require("../utils");
var lifecycle_1 = require("./lifecycle");
Object.defineProperty(exports, "initializeApp", { enumerable: true, get: function () { return lifecycle_1.initializeApp; } });
Object.defineProperty(exports, "getApp", { enumerable: true, get: function () { return lifecycle_1.getApp; } });
Object.defineProperty(exports, "getApps", { enumerable: true, get: function () { return lifecycle_1.getApps; } });
Object.defineProperty(exports, "deleteApp", { enumerable: true, get: function () { return lifecycle_1.deleteApp; } });
var credential_factory_1 = require("./credential-factory");
Object.defineProperty(exports, "applicationDefault", { enumerable: true, get: function () { return credential_factory_1.applicationDefault; } });
Object.defineProperty(exports, "cert", { enumerable: true, get: function () { return credential_factory_1.cert; } });
Object.defineProperty(exports, "refreshToken", { enumerable: true, get: function () { return credential_factory_1.refreshToken; } });
var error_1 = require("../utils/error");
Object.defineProperty(exports, "FirebaseAppError", { enumerable: true, get: function () { return error_1.FirebaseAppError; } });
Object.defineProperty(exports, "AppErrorCodes", { enumerable: true, get: function () { return error_1.AppErrorCodes; } });
exports.SDK_VERSION = (0, utils_1.getSdkVersion)();

View File

@@ -0,0 +1,116 @@
/*! firebase-admin v13.5.0 */
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { App, AppOptions } from './core';
export declare class AppStore {
private readonly appStore;
initializeApp(options?: AppOptions, appName?: string): App;
getApp(appName?: string): App;
getApps(): App[];
deleteApp(app: App): Promise<void>;
clearAllApps(): Promise<void>;
/**
* Removes the specified App instance from the store. This is currently called by the
* {@link FirebaseApp.delete} method. Can be removed once the app deletion is handled
* entirely by the {@link deleteApp} top-level function.
*/
removeApp(appName: string): void;
}
export declare const defaultAppStore: AppStore;
/**
* Initializes the `App` instance.
*
* Creates a new instance of {@link App} if one doesn't exist, or returns an existing
* `App` instance if one exists with the same `appName` and `options`.
*
* Note, due to the inablity to compare `http.Agent` objects and `Credential` objects,
* this function cannot support idempotency if either of `options.httpAgent` or
* `options.credential` are defined. When either is defined, subsequent invocations will
* throw a `FirebaseAppError` instead of returning an `App` object.
*
* For example, to safely initialize an app that may already exist:
*
* ```javascript
* let app;
* try {
* app = getApp("myApp");
* } catch (error) {
* app = initializeApp({ credential: myCredential }, "myApp");
* }
* ```
*
* @param options - Optional A set of {@link AppOptions} for the `App` instance.
* If not present, `initializeApp` will try to initialize with the options from the
* `FIREBASE_CONFIG` environment variable. If the environment variable contains a
* string that starts with `{` it will be parsed as JSON, otherwise it will be
* assumed to be pointing to a file.
* @param appName - Optional name of the `App` instance.
*
* @returns A new App instance, or the existing App if the instance already exists with
* the provided configuration.
*
* @throws FirebaseAppError if an `App` with the same name has already been
* initialized with a different set of `AppOptions`.
* @throws FirebaseAppError if an existing `App` exists and `options.httpAgent`
* or `options.credential` are defined. This is due to the function's inability to
* determine if the existing `App`'s `options` equate to the `options` parameter
* of this function. It's recommended to use {@link getApp} or {@link getApps} if your
* implementation uses either of these two fields in `AppOptions`.
*/
export declare function initializeApp(options?: AppOptions, appName?: string): App;
/**
* Returns an existing {@link App} instance for the provided name. If no name
* is provided the the default app name is used.
*
* @param appName - Optional name of the `App` instance.
*
* @returns An existing `App` instance that matches the name provided.
*
* @throws FirebaseAppError if no `App` exists for the given name.
* @throws FirebaseAppError if the `appName` is malformed.
*/
export declare function getApp(appName?: string): App;
/**
* A (read-only) array of all initialized apps.
*
* @returns An array containing all initialized apps.
*/
export declare function getApps(): App[];
/**
* Renders this given `App` unusable and frees the resources of
* all associated services (though it does *not* clean up any backend
* resources). When running the SDK locally, this method
* must be called to ensure graceful termination of the process.
*
* @example
* ```javascript
* deleteApp(app)
* .then(function() {
* console.log("App deleted successfully");
* })
* .catch(function(error) {
* console.log("Error deleting app:", error);
* });
* ```
*/
export declare function deleteApp(app: App): Promise<void>;
/**
* Constant holding the environment variable name with the default config.
* If the environment variable contains a string that starts with '{' it will be parsed as JSON,
* otherwise it will be assumed to be pointing to a file.
*/
export declare const FIREBASE_CONFIG_VAR = "FIREBASE_CONFIG";

277
server/node_modules/firebase-admin/lib/app/lifecycle.js generated vendored Normal file
View File

@@ -0,0 +1,277 @@
/*! firebase-admin v13.5.0 */
"use strict";
/*!
* @license
* Copyright 2021 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.FIREBASE_CONFIG_VAR = exports.defaultAppStore = exports.AppStore = void 0;
exports.initializeApp = initializeApp;
exports.getApp = getApp;
exports.getApps = getApps;
exports.deleteApp = deleteApp;
const fs = require("fs");
const validator = require("../utils/validator");
const error_1 = require("../utils/error");
const credential_internal_1 = require("./credential-internal");
const firebase_app_1 = require("./firebase-app");
const fastDeepEqual = require('fast-deep-equal');
const DEFAULT_APP_NAME = '[DEFAULT]';
class AppStore {
constructor() {
this.appStore = new Map();
}
initializeApp(options, appName = DEFAULT_APP_NAME) {
validateAppNameFormat(appName);
let autoInit = false;
if (typeof options === 'undefined') {
autoInit = true;
options = loadOptionsFromEnvVar();
options.credential = (0, credential_internal_1.getApplicationDefault)();
}
// Check if an app already exists and, if so, ensure its `AppOptions` match
// those of this `initializeApp` request.
if (!this.appStore.has(appName)) {
const app = new firebase_app_1.FirebaseApp(options, appName, autoInit, this);
this.appStore.set(app.name, app);
return app;
}
const currentApp = this.appStore.get(appName);
// Ensure the `autoInit` state matches the existing app's. If not, throw.
if (currentApp.autoInit() !== autoInit) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, `A Firebase app named "${appName}" already exists with a different configuration.`);
}
if (autoInit) {
// Auto-initialization is triggered when no options were passed to
// `initializeApp`. With no options to compare, simply return the App.
return currentApp;
}
// Ensure the options objects don't break deep equal comparisons.
validateAppOptionsSupportDeepEquals(options, currentApp);
// `FirebaseApp()` adds a synthesized `Credential` to `app.options` upon
// app construction. Run a comparison w/o `Credential` to see if the base
// configurations match. Return the existing app if so.
const currentAppOptions = { ...currentApp.options };
delete currentAppOptions.credential;
if (!fastDeepEqual(options, currentAppOptions)) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.DUPLICATE_APP, `A Firebase app named "${appName}" already exists with a different configuration.`);
}
return currentApp;
}
getApp(appName = DEFAULT_APP_NAME) {
validateAppNameFormat(appName);
if (!this.appStore.has(appName)) {
let errorMessage = (appName === DEFAULT_APP_NAME)
? 'The default Firebase app does not exist. ' : `Firebase app named "${appName}" does not exist. `;
errorMessage += 'Make sure you call initializeApp() before using any of the Firebase services.';
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.NO_APP, errorMessage);
}
return this.appStore.get(appName);
}
getApps() {
// Return a copy so the caller cannot mutate the array
return Array.from(this.appStore.values());
}
deleteApp(app) {
if (typeof app !== 'object' || app === null || !('options' in app)) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_ARGUMENT, 'Invalid app argument.');
}
// Make sure the given app already exists.
const existingApp = getApp(app.name);
// Delegate delete operation to the App instance itself. That will also remove the App
// instance from the AppStore.
return existingApp.delete();
}
clearAllApps() {
const promises = [];
this.getApps().forEach((app) => {
promises.push(this.deleteApp(app));
});
return Promise.all(promises).then();
}
/**
* Removes the specified App instance from the store. This is currently called by the
* {@link FirebaseApp.delete} method. Can be removed once the app deletion is handled
* entirely by the {@link deleteApp} top-level function.
*/
removeApp(appName) {
this.appStore.delete(appName);
}
}
exports.AppStore = AppStore;
/**
* Validates that the `requestedOptions` and the `existingApp` options objects
* do not have fields that would break deep equals comparisons.
*
* @param requestedOptions The incoming `AppOptions` of a new `initailizeApp`
* request.
* @param existingApp An existing `FirebaseApp` with internal `options` to
* compare against.
*
* @throws FirebaseAppError if the objects cannot be deeply compared.
*
* @internal
*/
function validateAppOptionsSupportDeepEquals(requestedOptions, existingApp) {
// http.Agent checks.
if (typeof requestedOptions.httpAgent !== 'undefined') {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, `Firebase app named "${existingApp.name}" already exists and initializeApp was` +
' invoked with an optional http.Agent. The SDK cannot confirm the equality' +
' of http.Agent objects with the existing app. Please use getApp or getApps to reuse' +
' the existing app instead.');
}
else if (typeof existingApp.options.httpAgent !== 'undefined') {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, `An existing app named "${existingApp.name}" already exists with a different` +
' options configuration: httpAgent.');
}
// Credential checks.
if (typeof requestedOptions.credential !== 'undefined') {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, `Firebase app named "${existingApp.name}" already exists and initializeApp was` +
' invoked with an optional Credential. The SDK cannot confirm the equality' +
' of Credential objects with the existing app. Please use getApp or getApps' +
' to reuse the existing app instead.');
}
if (existingApp.customCredential()) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, `An existing app named "${existingApp.name}" already exists with a different` +
' options configuration: Credential.');
}
}
/**
* Checks to see if the provided appName is a non-empty string and throws if it
* is not.
*
* @param appName A string representation of an App name.
*
* @throws FirebaseAppError if appName is not of type string or is empty.
*
* @internal
*/
function validateAppNameFormat(appName) {
if (!validator.isNonEmptyString(appName)) {
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_NAME, `Invalid Firebase app name "${appName}" provided. App name must be a non-empty string.`);
}
}
exports.defaultAppStore = new AppStore();
/**
* Initializes the `App` instance.
*
* Creates a new instance of {@link App} if one doesn't exist, or returns an existing
* `App` instance if one exists with the same `appName` and `options`.
*
* Note, due to the inablity to compare `http.Agent` objects and `Credential` objects,
* this function cannot support idempotency if either of `options.httpAgent` or
* `options.credential` are defined. When either is defined, subsequent invocations will
* throw a `FirebaseAppError` instead of returning an `App` object.
*
* For example, to safely initialize an app that may already exist:
*
* ```javascript
* let app;
* try {
* app = getApp("myApp");
* } catch (error) {
* app = initializeApp({ credential: myCredential }, "myApp");
* }
* ```
*
* @param options - Optional A set of {@link AppOptions} for the `App` instance.
* If not present, `initializeApp` will try to initialize with the options from the
* `FIREBASE_CONFIG` environment variable. If the environment variable contains a
* string that starts with `{` it will be parsed as JSON, otherwise it will be
* assumed to be pointing to a file.
* @param appName - Optional name of the `App` instance.
*
* @returns A new App instance, or the existing App if the instance already exists with
* the provided configuration.
*
* @throws FirebaseAppError if an `App` with the same name has already been
* initialized with a different set of `AppOptions`.
* @throws FirebaseAppError if an existing `App` exists and `options.httpAgent`
* or `options.credential` are defined. This is due to the function's inability to
* determine if the existing `App`'s `options` equate to the `options` parameter
* of this function. It's recommended to use {@link getApp} or {@link getApps} if your
* implementation uses either of these two fields in `AppOptions`.
*/
function initializeApp(options, appName = DEFAULT_APP_NAME) {
return exports.defaultAppStore.initializeApp(options, appName);
}
/**
* Returns an existing {@link App} instance for the provided name. If no name
* is provided the the default app name is used.
*
* @param appName - Optional name of the `App` instance.
*
* @returns An existing `App` instance that matches the name provided.
*
* @throws FirebaseAppError if no `App` exists for the given name.
* @throws FirebaseAppError if the `appName` is malformed.
*/
function getApp(appName = DEFAULT_APP_NAME) {
return exports.defaultAppStore.getApp(appName);
}
/**
* A (read-only) array of all initialized apps.
*
* @returns An array containing all initialized apps.
*/
function getApps() {
return exports.defaultAppStore.getApps();
}
/**
* Renders this given `App` unusable and frees the resources of
* all associated services (though it does *not* clean up any backend
* resources). When running the SDK locally, this method
* must be called to ensure graceful termination of the process.
*
* @example
* ```javascript
* deleteApp(app)
* .then(function() {
* console.log("App deleted successfully");
* })
* .catch(function(error) {
* console.log("Error deleting app:", error);
* });
* ```
*/
function deleteApp(app) {
return exports.defaultAppStore.deleteApp(app);
}
/**
* Constant holding the environment variable name with the default config.
* If the environment variable contains a string that starts with '{' it will be parsed as JSON,
* otherwise it will be assumed to be pointing to a file.
*/
exports.FIREBASE_CONFIG_VAR = 'FIREBASE_CONFIG';
/**
* Parse the file pointed to by the FIREBASE_CONFIG_VAR, if it exists.
* Or if the FIREBASE_CONFIG_ENV contains a valid JSON object, parse it directly.
* If the environment variable contains a string that starts with '{' it will be parsed as JSON,
* otherwise it will be assumed to be pointing to a file.
*/
function loadOptionsFromEnvVar() {
const config = process.env[exports.FIREBASE_CONFIG_VAR];
if (!validator.isNonEmptyString(config)) {
return {};
}
try {
const contents = config.startsWith('{') ? config : fs.readFileSync(config, 'utf8');
return JSON.parse(contents);
}
catch (error) {
// Throw a nicely formed error message if the file contents cannot be parsed
throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, 'Failed to parse app options file: ' + error);
}
}