@fusionauth/angular-sdk 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +5 -0
  2. package/esm2022/lib/SSRCookieAdapter.mjs +23 -0
  3. package/esm2022/lib/fusion-auth.module.mjs +4 -5
  4. package/esm2022/lib/fusion-auth.service.mjs +23 -3
  5. package/esm2022/lib/injectionToken.mjs +3 -0
  6. package/esm2022/lib/types.mjs +1 -1
  7. package/esm2022/sdkcore/CookieHelpers/CookieHelpers.mjs +34 -0
  8. package/esm2022/sdkcore/CookieHelpers/index.mjs +2 -0
  9. package/esm2022/sdkcore/RedirectHelper/RedirectHelper.mjs +47 -0
  10. package/esm2022/sdkcore/RedirectHelper/index.mjs +2 -0
  11. package/esm2022/sdkcore/SDKConfig/SDKConfig.mjs +2 -0
  12. package/esm2022/sdkcore/SDKConfig/index.mjs +2 -0
  13. package/esm2022/sdkcore/SDKContext/SDKContext.mjs +2 -0
  14. package/esm2022/sdkcore/SDKContext/index.mjs +2 -0
  15. package/esm2022/sdkcore/SDKCore/SDKCore.mjs +103 -0
  16. package/esm2022/sdkcore/SDKCore/index.mjs +2 -0
  17. package/esm2022/sdkcore/UrlHelper/UrlHelper.mjs +64 -0
  18. package/esm2022/sdkcore/UrlHelper/UrlHelperTypes.mjs +2 -0
  19. package/esm2022/sdkcore/UrlHelper/index.mjs +3 -0
  20. package/esm2022/sdkcore/index.mjs +5 -0
  21. package/esm2022/sdkcore/testUtils/index.mjs +3 -0
  22. package/esm2022/sdkcore/testUtils/mockLoggedIn.mjs +13 -0
  23. package/esm2022/sdkcore/testUtils/mockWindowLocation.mjs +10 -0
  24. package/fesm2022/fusionauth-angular-sdk.mjs +248 -183
  25. package/fesm2022/fusionauth-angular-sdk.mjs.map +1 -1
  26. package/lib/SSRCookieAdapter.d.ts +7 -0
  27. package/lib/fusion-auth.service.d.ts +6 -3
  28. package/lib/injectionToken.d.ts +3 -0
  29. package/lib/types.d.ts +8 -0
  30. package/package.json +3 -3
  31. package/sdkcore/CookieHelpers/CookieHelpers.d.ts +11 -0
  32. package/sdkcore/CookieHelpers/index.d.ts +1 -0
  33. package/sdkcore/RedirectHelper/RedirectHelper.d.ts +10 -0
  34. package/sdkcore/RedirectHelper/index.d.ts +1 -0
  35. package/sdkcore/SDKConfig/SDKConfig.d.ts +79 -0
  36. package/sdkcore/SDKConfig/index.d.ts +1 -0
  37. package/sdkcore/SDKContext/SDKContext.d.ts +65 -0
  38. package/sdkcore/SDKContext/index.d.ts +1 -0
  39. package/sdkcore/SDKCore/SDKCore.d.ts +23 -0
  40. package/sdkcore/SDKCore/index.d.ts +1 -0
  41. package/sdkcore/UrlHelper/UrlHelper.d.ts +22 -0
  42. package/sdkcore/UrlHelper/UrlHelperTypes.d.ts +11 -0
  43. package/sdkcore/UrlHelper/index.d.ts +2 -0
  44. package/sdkcore/index.d.ts +5 -0
  45. package/sdkcore/testUtils/index.d.ts +2 -0
  46. package/sdkcore/testUtils/mockLoggedIn.d.ts +5 -0
  47. package/sdkcore/testUtils/mockWindowLocation.d.ts +18 -0
  48. package/esm2022/lib/core.mjs +0 -241
  49. package/lib/core.d.ts +0 -57
@@ -1,57 +1,45 @@
1
- import { BehaviorSubject, Observable, catchError } from 'rxjs';
2
1
  import * as i0 from '@angular/core';
3
- import { Component, Input, NgModule } from '@angular/core';
2
+ import { InjectionToken, PLATFORM_ID, Injectable, Inject, Component, Input, NgModule } from '@angular/core';
3
+ import { isPlatformBrowser } from '@angular/common';
4
+ import { BehaviorSubject, Observable, catchError } from 'rxjs';
4
5
 
5
- // @ts-nocheck
6
- const u = Object.defineProperty;
7
- const d = (r, e, t) => e in r
8
- ? u(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t })
9
- : (r[e] = t);
10
- const i = (r, e, t) => (d(r, typeof e != 'symbol' ? e + '' : e, t), t);
11
- class g {
12
- constructor(e) {
13
- i(this, 'serverUrl');
14
- i(this, 'clientId');
15
- i(this, 'redirectUri');
16
- i(this, 'scope');
17
- i(this, 'mePath');
18
- i(this, 'loginPath');
19
- i(this, 'registerPath');
20
- i(this, 'logoutPath');
21
- i(this, 'tokenRefreshPath');
22
- (this.serverUrl = e.serverUrl),
23
- (this.clientId = e.clientId),
24
- (this.redirectUri = e.redirectUri),
25
- (this.scope = e.scope),
26
- (this.mePath = e.mePath ?? '/app/me'),
27
- (this.loginPath = e.loginPath ?? '/app/login'),
28
- (this.registerPath = e.registerPath ?? '/app/register'),
29
- (this.logoutPath = e.logoutPath ?? '/app/logout'),
30
- (this.tokenRefreshPath = e.tokenRefreshPath ?? '/app/refresh');
6
+ /** A class responsible for generating URLs that FusionAuth SDKs interact with. */
7
+ class UrlHelper {
8
+ constructor(config) {
9
+ this.serverUrl = config.serverUrl;
10
+ this.clientId = config.clientId;
11
+ this.redirectUri = config.redirectUri;
12
+ this.scope = config.scope;
13
+ this.postLogoutRedirectUri = config.postLogoutRedirectUri;
14
+ this.mePath = config.mePath ?? '/app/me';
15
+ this.loginPath = config.loginPath ?? '/app/login';
16
+ this.registerPath = config.registerPath ?? '/app/register';
17
+ this.logoutPath = config.logoutPath ?? '/app/logout';
18
+ this.tokenRefreshPath = config.tokenRefreshPath ?? '/app/refresh';
31
19
  }
32
20
  getMeUrl() {
33
21
  return this.generateUrl(this.mePath);
34
22
  }
35
- getLoginUrl(e) {
23
+ getLoginUrl(state) {
36
24
  return this.generateUrl(this.loginPath, {
37
25
  client_id: this.clientId,
38
26
  redirect_uri: this.redirectUri,
39
27
  scope: this.scope,
40
- state: e,
28
+ state,
41
29
  });
42
30
  }
43
- getRegisterUrl(e) {
31
+ getRegisterUrl(state) {
44
32
  return this.generateUrl(this.registerPath, {
45
33
  client_id: this.clientId,
46
34
  redirect_uri: this.redirectUri,
47
35
  scope: this.scope,
48
- state: e,
36
+ state,
49
37
  });
50
38
  }
51
39
  getLogoutUrl() {
52
40
  return this.generateUrl(this.logoutPath, {
53
41
  client_id: this.clientId,
54
- post_logout_redirect_uri: this.redirectUri,
42
+ post_logout_redirect_uri: this.postLogoutRedirectUri || this.redirectUri,
55
43
  });
56
44
  }
57
45
  getTokenRefreshUrl() {
@@ -59,199 +47,264 @@ class g {
59
47
  client_id: this.clientId,
60
48
  });
61
49
  }
62
- generateUrl(e, t) {
63
- const s = new URL(this.serverUrl);
64
- if (((s.pathname = e), t)) {
65
- const n = this.generateURLSearchParams(t);
66
- s.search = n.toString();
50
+ generateUrl(path, params) {
51
+ const url = new URL(this.serverUrl);
52
+ url.pathname = path;
53
+ if (params) {
54
+ const urlSearchParams = this.generateURLSearchParams(params);
55
+ url.search = urlSearchParams.toString();
67
56
  }
68
- return s;
69
- }
70
- generateURLSearchParams(e) {
71
- const t = new URLSearchParams();
72
- return (Object.entries(e).forEach(([s, n]) => {
73
- n && t.append(s, n);
74
- }),
75
- t);
76
- }
77
- }
78
- class o {
79
- /**
80
- * Parses document.cookie for the access token expiration cookie value.
81
- * @returns {(number | null)} The moment of expiration in milliseconds since epoch.
82
- */
83
- static getAccessTokenExpirationMoment(e = 'app.at_exp') {
84
- const t = document.cookie
85
- .split('; ')
86
- .map(n => n.split('='))
87
- .find(([n]) => n === e), s = t == null ? void 0 : t[1];
88
- return s ? parseInt(s) * 1e3 : null;
89
- }
90
- }
91
- class p {
92
- constructor(e) {
93
- i(this, 'url');
94
- this.url = e;
57
+ return url;
95
58
  }
96
- /** Refresh token a single time */
97
- async refreshToken() {
98
- const e = await fetch(this.url.href, {
99
- method: 'POST',
100
- credentials: 'include',
101
- headers: {
102
- 'Content-Type': 'text/plain',
103
- },
104
- });
105
- if (!(e.status >= 200 && e.status < 300))
106
- throw new Error('error refreshing access token in fusionauth');
107
- }
108
- /** Initializes continuous automatic token refresh. */
109
- initAutoRefresh(e = 10, t) {
110
- const s = o.getAccessTokenExpirationMoment(t);
111
- if (!s)
112
- return;
113
- const n = e * 1e3, a = /* @__PURE__ */ new Date().getTime(), h = s - n, c = Math.max(h - a, 0);
114
- return setTimeout(async () => {
115
- try {
116
- await this.refreshToken(), this.initAutoRefresh(e);
117
- }
118
- catch (l) {
119
- console.error(l);
59
+ generateURLSearchParams(params) {
60
+ const urlSearchParams = new URLSearchParams();
61
+ Object.entries(params).forEach(([key, value]) => {
62
+ if (value) {
63
+ urlSearchParams.append(key, value);
120
64
  }
121
- }, c);
122
- }
123
- }
124
- class m {
125
- /**
126
- * Schedules a callback to be invoked at the given moment.
127
- * @param expirationMoment - the access token expiration moment in milliseconds since the epoch.
128
- * @param onExpiration - the callback to be invoked at the `expirationMoment`.
129
- */
130
- static scheduleTokenExpirationCallback(e, t) {
131
- const s = /* @__PURE__ */ new Date().getTime(), n = e - s;
132
- n > 0 && setTimeout(t, n);
65
+ });
66
+ return urlSearchParams;
133
67
  }
134
68
  }
135
- class R {
69
+
70
+ /** A class responsible for storing a redirect value in localStorage and cleanup afterward. */
71
+ class RedirectHelper {
136
72
  constructor() {
137
- i(this, 'REDIRECT_VALUE', 'fa-sdk-redirect-value');
73
+ this.REDIRECT_VALUE = 'fa-sdk-redirect-value';
138
74
  }
139
- handlePreRedirect(e) {
140
- const t = `${this.generateRandomString()}:${e ?? ''}`;
141
- localStorage.setItem(this.REDIRECT_VALUE, t);
75
+ get storage() {
76
+ try {
77
+ return localStorage;
78
+ }
79
+ catch {
80
+ // fallback for non-browser environments where localStorage is not defined.
81
+ return {
82
+ /* eslint-disable */
83
+ setItem(_key, _value) { },
84
+ getItem(_key) { },
85
+ removeItem(_key) { },
86
+ /* eslint-enable */
87
+ };
88
+ }
89
+ }
90
+ handlePreRedirect(state) {
91
+ const valueForStorage = `${this.generateRandomString()}:${state ?? ''}`;
92
+ this.storage.setItem(this.REDIRECT_VALUE, valueForStorage);
142
93
  }
143
- handlePostRedirect(e) {
144
- const t = this.stateValue ?? void 0;
145
- e == null || e(t), localStorage.removeItem(this.REDIRECT_VALUE);
94
+ handlePostRedirect(callback) {
95
+ const stateValue = this.stateValue ?? undefined;
96
+ callback?.(stateValue);
97
+ this.storage.removeItem(this.REDIRECT_VALUE);
146
98
  }
147
99
  get didRedirect() {
148
- return !!localStorage.getItem(this.REDIRECT_VALUE);
100
+ return Boolean(this.storage.getItem(this.REDIRECT_VALUE));
149
101
  }
150
102
  get stateValue() {
151
- const e = localStorage.getItem(this.REDIRECT_VALUE);
152
- if (!e)
103
+ const redirectValue = this.storage.getItem(this.REDIRECT_VALUE);
104
+ if (!redirectValue) {
153
105
  return null;
154
- const [, ...t] = e.split(':');
155
- return t.join(':');
106
+ }
107
+ const [, ...stateValue] = redirectValue.split(':');
108
+ return stateValue.join(':');
156
109
  }
157
110
  generateRandomString() {
158
- const e = new Uint32Array(28);
159
- return (window.crypto.getRandomValues(e),
160
- Array.from(e, t => ('0' + t.toString(16)).substring(-2)).join(''));
111
+ const array = new Uint32Array(56 / 2);
112
+ window.crypto.getRandomValues(array);
113
+ return Array.from(array, (n) => ('0' + n.toString(16)).substring(-2)).join('');
161
114
  }
162
115
  }
163
- class T {
164
- constructor(e) {
165
- i(this, 'config');
166
- i(this, 'urlHelper');
167
- i(this, 'tokenRefresher');
168
- i(this, 'redirectHelper', new R());
169
- (this.config = e),
170
- (this.urlHelper = new g({
171
- serverUrl: e.serverUrl,
172
- clientId: e.clientId,
173
- redirectUri: e.redirectUri,
174
- scope: e.scope,
175
- mePath: e.mePath,
176
- loginPath: e.loginPath,
177
- registerPath: e.registerPath,
178
- logoutPath: e.logoutPath,
179
- tokenRefreshPath: e.tokenRefreshPath,
180
- })),
181
- (this.tokenRefresher = new p(this.urlHelper.getTokenRefreshUrl())),
182
- this.scheduleTokenExpirationEvent();
183
- }
184
- startLogin(e) {
185
- this.redirectHelper.handlePreRedirect(e),
186
- window.location.assign(this.urlHelper.getLoginUrl(e));
187
- }
188
- startRegister(e) {
189
- this.redirectHelper.handlePreRedirect(e),
190
- window.location.assign(this.urlHelper.getRegisterUrl(e));
116
+
117
+ /**
118
+ * Gets the `app.at_exp` cookie and converts it to milliseconds since epoch.
119
+ * Returns -1 if the cookie is not present.
120
+ * @param cookieName - defaults to `app.at_exp`.
121
+ * @param adapter - SSR frameworks like Nuxt, Next, and angular/ssr will pass in an adapter.
122
+ */
123
+ function getAccessTokenExpirationMoment(cookieName = 'app.at_exp', adapter) {
124
+ if (adapter) {
125
+ return toMilliseconds(adapter.at_exp(cookieName));
126
+ }
127
+ let cookie;
128
+ try {
129
+ // `document` throws a ReferenceError if this runs in a
130
+ // non-browser environment such as an SSR framework like Nuxt or Next.
131
+ cookie = document.cookie;
132
+ }
133
+ catch {
134
+ console.error('Error accessing cookies in fusionauth. If you are using SSR you must configure the SDK with a cookie adapter');
135
+ return -1;
136
+ }
137
+ const expCookie = cookie
138
+ .split('; ')
139
+ .map(c => c.split('='))
140
+ .find(([name]) => name === cookieName);
141
+ const cookieValue = expCookie?.[1];
142
+ return toMilliseconds(cookieValue);
143
+ }
144
+ function toMilliseconds(seconds) {
145
+ if (!seconds)
146
+ return -1;
147
+ else
148
+ return Number(seconds) * 1000;
149
+ }
150
+
151
+ /** A class containing framework-agnostic SDK methods */
152
+ class SDKCore {
153
+ constructor(config) {
154
+ this.redirectHelper = new RedirectHelper();
155
+ this.config = config;
156
+ this.urlHelper = new UrlHelper({
157
+ serverUrl: config.serverUrl,
158
+ clientId: config.clientId,
159
+ redirectUri: config.redirectUri,
160
+ scope: config.scope,
161
+ mePath: config.mePath,
162
+ loginPath: config.loginPath,
163
+ registerPath: config.registerPath,
164
+ logoutPath: config.logoutPath,
165
+ tokenRefreshPath: config.tokenRefreshPath,
166
+ postLogoutRedirectUri: config.postLogoutRedirectUri,
167
+ });
168
+ this.scheduleTokenExpiration();
169
+ }
170
+ startLogin(state) {
171
+ this.redirectHelper.handlePreRedirect(state);
172
+ window.location.assign(this.urlHelper.getLoginUrl(state));
173
+ }
174
+ startRegister(state) {
175
+ this.redirectHelper.handlePreRedirect(state);
176
+ window.location.assign(this.urlHelper.getRegisterUrl(state));
191
177
  }
192
178
  startLogout() {
193
179
  window.location.assign(this.urlHelper.getLogoutUrl());
194
180
  }
195
181
  async fetchUserInfo() {
196
- const e = await fetch(this.urlHelper.getMeUrl(), {
182
+ const userInfoResponse = await fetch(this.urlHelper.getMeUrl(), {
197
183
  credentials: 'include',
198
184
  });
199
- if (!e.ok)
200
- throw new Error(`Unable to fetch userInfo in fusionauth. Request failed with status code ${e == null ? void 0 : e.status}`);
201
- return await e.json();
185
+ if (!userInfoResponse.ok) {
186
+ throw new Error(`Unable to fetch userInfo in fusionauth. Request failed with status code ${userInfoResponse?.status}`);
187
+ }
188
+ const userInfo = await userInfoResponse.json();
189
+ return userInfo;
202
190
  }
203
191
  async refreshToken() {
204
- return await this.tokenRefresher.refreshToken();
192
+ const response = await fetch(this.urlHelper.getTokenRefreshUrl(), {
193
+ method: 'POST',
194
+ credentials: 'include',
195
+ headers: {
196
+ 'Content-Type': 'text/plain',
197
+ },
198
+ });
199
+ if (!(response.status >= 200 && response.status < 300)) {
200
+ const message = (await response?.text()) ||
201
+ 'Error refreshing access token in fusionauth';
202
+ throw new Error(message);
203
+ }
204
+ // a successful request means that app_exp was bumped into the future.
205
+ // reschedule the access token expiration event.
206
+ this.scheduleTokenExpiration();
207
+ return response;
205
208
  }
206
209
  initAutoRefresh() {
207
- return this.tokenRefresher.initAutoRefresh(this.config.autoRefreshSecondsBeforeExpiry, this.config.accessTokenExpireCookieName);
210
+ if (!this.isLoggedIn) {
211
+ return;
212
+ }
213
+ const secondsBeforeRefresh = this.config.autoRefreshSecondsBeforeExpiry ?? 10;
214
+ const millisecondsBeforeRefresh = secondsBeforeRefresh * 1000;
215
+ const now = new Date().getTime();
216
+ const refreshTime = this.at_exp - millisecondsBeforeRefresh;
217
+ const timeTillRefresh = Math.max(refreshTime - now, 0);
218
+ return setTimeout(async () => {
219
+ try {
220
+ await this.refreshToken();
221
+ this.initAutoRefresh();
222
+ }
223
+ catch (error) {
224
+ this.config.onAutoRefreshFailure?.(error);
225
+ }
226
+ }, timeTillRefresh);
208
227
  }
209
- handlePostRedirect(e) {
210
- this.isLoggedIn &&
211
- this.redirectHelper.didRedirect &&
212
- this.redirectHelper.handlePostRedirect(e);
228
+ handlePostRedirect(callback) {
229
+ if (this.isLoggedIn && this.redirectHelper.didRedirect) {
230
+ this.redirectHelper.handlePostRedirect(callback);
231
+ }
213
232
  }
214
233
  get isLoggedIn() {
215
- return this.accessTokenExpirationMoment
216
- ? this.accessTokenExpirationMoment > /* @__PURE__ */ new Date().getTime()
217
- : !1;
218
- }
219
- get accessTokenExpirationMoment() {
220
- return o.getAccessTokenExpirationMoment(this.config.accessTokenExpireCookieName);
221
- }
222
- scheduleTokenExpirationEvent() {
223
- this.accessTokenExpirationMoment &&
224
- this.config.onTokenExpiration &&
225
- m.scheduleTokenExpirationCallback(this.accessTokenExpirationMoment, this.config.onTokenExpiration);
234
+ return this.at_exp > new Date().getTime();
235
+ }
236
+ /** The moment of access token expiration in milliseconds since epoch. */
237
+ get at_exp() {
238
+ return getAccessTokenExpirationMoment(this.config.accessTokenExpireCookieName, this.config.cookieAdapter);
239
+ }
240
+ /** Schedules `onTokenExpiration` at moment of access token expiration. */
241
+ scheduleTokenExpiration() {
242
+ clearTimeout(this.tokenExpirationTimeout);
243
+ const now = new Date().getTime();
244
+ const millisecondsTillExpiration = this.at_exp - now;
245
+ if (millisecondsTillExpiration > 0) {
246
+ this.tokenExpirationTimeout = setTimeout(this.config.onTokenExpiration, millisecondsTillExpiration);
247
+ }
226
248
  }
227
249
  }
228
- function U() {
229
- const r = /* @__PURE__ */ new Date();
230
- r.setHours(r.getHours() + 1);
231
- const e = r.getTime() / 1e3;
232
- document.cookie = `app.at_exp=${e}`;
250
+
251
+ /** Sets `app.at_exp` moment cookie so the user will be logged in for 1 hour. */
252
+ function mockIsLoggedIn() {
253
+ const expirationMoment = new Date();
254
+ expirationMoment.setHours(expirationMoment.getHours() + 1);
255
+ const oneHourInTheFutureInMilliseconds = expirationMoment.getTime() / 1000;
256
+ document.cookie = `app.at_exp=${oneHourInTheFutureInMilliseconds}`;
233
257
  }
234
- function P() {
235
- document.cookie = 'app.at_exp=;expires=Thu, 01 Jan 1970 00:00:00 GMT';
258
+ /** Removes the `app.at_exp` cookie. */
259
+ function removeAt_expCookie() {
260
+ document.cookie = 'app.at_exp' + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT';
236
261
  }
237
- function E(r) {
238
- const e = {
262
+
263
+ function mockWindowLocation(vi) {
264
+ const mockedLocation = {
239
265
  ...window.location,
240
- assign: r.fn(),
266
+ assign: vi.fn(),
241
267
  };
242
- return r.spyOn(window, 'location', 'get').mockReturnValue(e), e;
268
+ vi.spyOn(window, 'location', 'get').mockReturnValue(mockedLocation);
269
+ return mockedLocation;
270
+ }
271
+
272
+ /** An adapter class that supports accessing cookies with SSR */
273
+ class SSRCookieAdapter {
274
+ constructor(isBrowser) {
275
+ this.isBrowser = isBrowser;
276
+ }
277
+ at_exp(cookieName = 'app.at_exp') {
278
+ if (!this.isBrowser) {
279
+ return;
280
+ }
281
+ try {
282
+ const expCookie = document.cookie
283
+ .split('; ')
284
+ .map(c => c.split('='))
285
+ .find(([name]) => name === cookieName);
286
+ return expCookie?.[1];
287
+ }
288
+ catch (error) {
289
+ console.error('Error within the SSRCookieAdapter: ', error);
290
+ return -1;
291
+ }
292
+ }
243
293
  }
244
294
 
295
+ const FUSIONAUTH_SERVICE_CONFIG = new InjectionToken('FUSIONAUTH_SERVICE_CONFIG');
296
+
245
297
  /**
246
298
  * Service class to use with FusionAuth backend endpoints.
247
299
  */
248
300
  class FusionAuthService {
249
- constructor(config) {
250
- this.core = new T({
301
+ constructor(config, platformId) {
302
+ this.core = new SDKCore({
251
303
  ...config,
252
304
  onTokenExpiration: () => {
253
305
  this.isLoggedInSubject.next(false);
254
306
  },
307
+ cookieAdapter: new SSRCookieAdapter(isPlatformBrowser(platformId)),
255
308
  });
256
309
  this.isLoggedInSubject = new BehaviorSubject(this.core.isLoggedIn);
257
310
  this.isLoggedIn$ = this.isLoggedInSubject.asObservable();
@@ -329,7 +382,21 @@ class FusionAuthService {
329
382
  logout() {
330
383
  this.core.startLogout();
331
384
  }
385
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthService, deps: [{ token: FUSIONAUTH_SERVICE_CONFIG }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
386
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthService, providedIn: 'root' }); }
332
387
  }
388
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthService, decorators: [{
389
+ type: Injectable,
390
+ args: [{
391
+ providedIn: 'root',
392
+ }]
393
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
394
+ type: Inject,
395
+ args: [FUSIONAUTH_SERVICE_CONFIG]
396
+ }] }, { type: Object, decorators: [{
397
+ type: Inject,
398
+ args: [PLATFORM_ID]
399
+ }] }] });
333
400
 
334
401
  class FusionAuthLoginButtonComponent {
335
402
  constructor(fusionAuth) {
@@ -385,10 +452,8 @@ class FusionAuthModule {
385
452
  return {
386
453
  ngModule: FusionAuthModule,
387
454
  providers: [
388
- {
389
- provide: FusionAuthService,
390
- useValue: new FusionAuthService(fusionAuthConfig),
391
- },
455
+ { provide: FUSIONAUTH_SERVICE_CONFIG, useValue: fusionAuthConfig },
456
+ FusionAuthService,
392
457
  ],
393
458
  };
394
459
  }