1 |
|
2 | "use strict";
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | Object.defineProperty(exports, "__esModule", { value: true });
|
20 | exports.FirebaseApp = exports.FirebaseAppInternals = void 0;
|
21 | var credential_internal_1 = require("./credential-internal");
|
22 | var validator = require("../utils/validator");
|
23 | var deep_copy_1 = require("../utils/deep-copy");
|
24 | var error_1 = require("../utils/error");
|
25 | var TOKEN_EXPIRY_THRESHOLD_MILLIS = 5 * 60 * 1000;
|
26 |
|
27 |
|
28 |
|
29 | var FirebaseAppInternals = (function () {
|
30 | function FirebaseAppInternals(credential_) {
|
31 | this.credential_ = credential_;
|
32 | this.tokenListeners_ = [];
|
33 | }
|
34 | FirebaseAppInternals.prototype.getToken = function (forceRefresh) {
|
35 | if (forceRefresh === void 0) { forceRefresh = false; }
|
36 | if (forceRefresh || this.shouldRefresh()) {
|
37 | return this.refreshToken();
|
38 | }
|
39 | return Promise.resolve(this.cachedToken_);
|
40 | };
|
41 | FirebaseAppInternals.prototype.getCachedToken = function () {
|
42 | return this.cachedToken_ || null;
|
43 | };
|
44 | FirebaseAppInternals.prototype.refreshToken = function () {
|
45 | var _this = this;
|
46 | return Promise.resolve(this.credential_.getAccessToken())
|
47 | .then(function (result) {
|
48 |
|
49 |
|
50 | if (!validator.isNonNullObject(result) ||
|
51 | typeof result.expires_in !== 'number' ||
|
52 | typeof result.access_token !== 'string') {
|
53 | throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, "Invalid access token generated: \"" + JSON.stringify(result) + "\". Valid access " +
|
54 | 'tokens must be an object with the "expires_in" (number) and "access_token" ' +
|
55 | '(string) properties.');
|
56 | }
|
57 | var token = {
|
58 | accessToken: result.access_token,
|
59 | expirationTime: Date.now() + (result.expires_in * 1000),
|
60 | };
|
61 | if (!_this.cachedToken_
|
62 | || _this.cachedToken_.accessToken !== token.accessToken
|
63 | || _this.cachedToken_.expirationTime !== token.expirationTime) {
|
64 |
|
65 |
|
66 | _this.cachedToken_ = token;
|
67 | _this.tokenListeners_.forEach(function (listener) {
|
68 | listener(token.accessToken);
|
69 | });
|
70 | }
|
71 | return token;
|
72 | })
|
73 | .catch(function (error) {
|
74 | var errorMessage = (typeof error === 'string') ? error : error.message;
|
75 | errorMessage = 'Credential implementation provided to initializeApp() via the ' +
|
76 | '"credential" property failed to fetch a valid Google OAuth2 access token with the ' +
|
77 | ("following error: \"" + errorMessage + "\".");
|
78 | if (errorMessage.indexOf('invalid_grant') !== -1) {
|
79 | errorMessage += ' There are two likely causes: (1) your server time is not properly ' +
|
80 | 'synced or (2) your certificate key file has been revoked. To solve (1), re-sync the ' +
|
81 | 'time on your server. To solve (2), make sure the key ID for your key file is still ' +
|
82 | 'present at https://console.firebase.google.com/iam-admin/serviceaccounts/project. If ' +
|
83 | 'not, generate a new key file at ' +
|
84 | 'https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk.';
|
85 | }
|
86 | throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_CREDENTIAL, errorMessage);
|
87 | });
|
88 | };
|
89 | FirebaseAppInternals.prototype.shouldRefresh = function () {
|
90 | return !this.cachedToken_ || (this.cachedToken_.expirationTime - Date.now()) <= TOKEN_EXPIRY_THRESHOLD_MILLIS;
|
91 | };
|
92 | |
93 |
|
94 |
|
95 |
|
96 |
|
97 | FirebaseAppInternals.prototype.addAuthTokenListener = function (listener) {
|
98 | this.tokenListeners_.push(listener);
|
99 | if (this.cachedToken_) {
|
100 | listener(this.cachedToken_.accessToken);
|
101 | }
|
102 | };
|
103 | |
104 |
|
105 |
|
106 |
|
107 |
|
108 | FirebaseAppInternals.prototype.removeAuthTokenListener = function (listener) {
|
109 | this.tokenListeners_ = this.tokenListeners_.filter(function (other) { return other !== listener; });
|
110 | };
|
111 | return FirebaseAppInternals;
|
112 | }());
|
113 | exports.FirebaseAppInternals = FirebaseAppInternals;
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 | var FirebaseApp = (function () {
|
120 | function FirebaseApp(options, name, appStore) {
|
121 | this.appStore = appStore;
|
122 | this.services_ = {};
|
123 | this.isDeleted_ = false;
|
124 | this.name_ = name;
|
125 | this.options_ = deep_copy_1.deepCopy(options);
|
126 | if (!validator.isNonNullObject(this.options_)) {
|
127 | throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, 'Invalid Firebase app options passed as the first argument to initializeApp() for the ' +
|
128 | ("app named \"" + this.name_ + "\". Options must be a non-null object."));
|
129 | }
|
130 | var hasCredential = ('credential' in this.options_);
|
131 | if (!hasCredential) {
|
132 | this.options_.credential = credential_internal_1.getApplicationDefault(this.options_.httpAgent);
|
133 | }
|
134 | var credential = this.options_.credential;
|
135 | if (typeof credential !== 'object' || credential === null || typeof credential.getAccessToken !== 'function') {
|
136 | throw new error_1.FirebaseAppError(error_1.AppErrorCodes.INVALID_APP_OPTIONS, 'Invalid Firebase app options passed as the first argument to initializeApp() for the ' +
|
137 | ("app named \"" + this.name_ + "\". The \"credential\" property must be an object which implements ") +
|
138 | 'the Credential interface.');
|
139 | }
|
140 | this.INTERNAL = new FirebaseAppInternals(credential);
|
141 | }
|
142 | Object.defineProperty(FirebaseApp.prototype, "name", {
|
143 | |
144 |
|
145 |
|
146 |
|
147 |
|
148 | get: function () {
|
149 | this.checkDestroyed_();
|
150 | return this.name_;
|
151 | },
|
152 | enumerable: false,
|
153 | configurable: true
|
154 | });
|
155 | Object.defineProperty(FirebaseApp.prototype, "options", {
|
156 | |
157 |
|
158 |
|
159 |
|
160 |
|
161 | get: function () {
|
162 | this.checkDestroyed_();
|
163 | return deep_copy_1.deepCopy(this.options_);
|
164 | },
|
165 | enumerable: false,
|
166 | configurable: true
|
167 | });
|
168 | |
169 |
|
170 |
|
171 | FirebaseApp.prototype.getOrInitService = function (name, init) {
|
172 | var _this = this;
|
173 | return this.ensureService_(name, function () { return init(_this); });
|
174 | };
|
175 | |
176 |
|
177 |
|
178 |
|
179 |
|
180 | FirebaseApp.prototype.delete = function () {
|
181 | var _this = this;
|
182 | var _a;
|
183 | this.checkDestroyed_();
|
184 |
|
185 |
|
186 |
|
187 | (_a = this.appStore) === null || _a === void 0 ? void 0 : _a.removeApp(this.name);
|
188 | return Promise.all(Object.keys(this.services_).map(function (serviceName) {
|
189 | var service = _this.services_[serviceName];
|
190 | if (isStateful(service)) {
|
191 | return service.delete();
|
192 | }
|
193 | return Promise.resolve();
|
194 | })).then(function () {
|
195 | _this.services_ = {};
|
196 | _this.isDeleted_ = true;
|
197 | });
|
198 | };
|
199 | FirebaseApp.prototype.ensureService_ = function (serviceName, initializer) {
|
200 | this.checkDestroyed_();
|
201 | if (!(serviceName in this.services_)) {
|
202 | this.services_[serviceName] = initializer();
|
203 | }
|
204 | return this.services_[serviceName];
|
205 | };
|
206 | |
207 |
|
208 |
|
209 | FirebaseApp.prototype.checkDestroyed_ = function () {
|
210 | if (this.isDeleted_) {
|
211 | throw new error_1.FirebaseAppError(error_1.AppErrorCodes.APP_DELETED, "Firebase app named \"" + this.name_ + "\" has already been deleted.");
|
212 | }
|
213 | };
|
214 | return FirebaseApp;
|
215 | }());
|
216 | exports.FirebaseApp = FirebaseApp;
|
217 | function isStateful(service) {
|
218 | return typeof service.delete === 'function';
|
219 | }
|