@fusionauth/angular-sdk 1.0.2 → 1.2.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 (57) hide show
  1. package/README.md +5 -0
  2. package/esm2022/lib/SSRCookieAdapter.mjs +23 -0
  3. package/esm2022/lib/components/fusionauth-account.button/fusion-auth-account-button.component.mjs +18 -0
  4. package/esm2022/lib/components/fusionauth-login.button/fusion-auth-login-button.component.mjs +4 -4
  5. package/esm2022/lib/components/fusionauth-logout.button/fusion-auth-logout-button.component.mjs +4 -4
  6. package/esm2022/lib/components/fusionauth-register.button/fusion-auth-register-button.component.mjs +4 -4
  7. package/esm2022/lib/fusion-auth.module.mjs +15 -11
  8. package/esm2022/lib/fusion-auth.service.mjs +30 -3
  9. package/esm2022/lib/injectionToken.mjs +3 -0
  10. package/esm2022/lib/types.mjs +1 -1
  11. package/esm2022/public-api.mjs +2 -1
  12. package/esm2022/sdkcore/CookieHelpers/CookieHelpers.mjs +34 -0
  13. package/esm2022/sdkcore/CookieHelpers/index.mjs +2 -0
  14. package/esm2022/sdkcore/RedirectHelper/RedirectHelper.mjs +47 -0
  15. package/esm2022/sdkcore/RedirectHelper/index.mjs +2 -0
  16. package/esm2022/sdkcore/SDKConfig/SDKConfig.mjs +2 -0
  17. package/esm2022/sdkcore/SDKConfig/index.mjs +2 -0
  18. package/esm2022/sdkcore/SDKContext/SDKContext.mjs +2 -0
  19. package/esm2022/sdkcore/SDKContext/index.mjs +2 -0
  20. package/esm2022/sdkcore/SDKCore/SDKCore.mjs +110 -0
  21. package/esm2022/sdkcore/SDKCore/index.mjs +2 -0
  22. package/esm2022/sdkcore/UrlHelper/UrlHelper.mjs +69 -0
  23. package/esm2022/sdkcore/UrlHelper/UrlHelperTypes.mjs +2 -0
  24. package/esm2022/sdkcore/UrlHelper/index.mjs +3 -0
  25. package/esm2022/sdkcore/index.mjs +5 -0
  26. package/esm2022/sdkcore/testUtils/index.mjs +3 -0
  27. package/esm2022/sdkcore/testUtils/mockLoggedIn.mjs +13 -0
  28. package/esm2022/sdkcore/testUtils/mockWindowLocation.mjs +10 -0
  29. package/fesm2022/fusionauth-angular-sdk.mjs +282 -155
  30. package/fesm2022/fusionauth-angular-sdk.mjs.map +1 -1
  31. package/lib/SSRCookieAdapter.d.ts +7 -0
  32. package/lib/components/fusionauth-account.button/fusion-auth-account-button.component.d.ts +9 -0
  33. package/lib/fusion-auth.module.d.ts +2 -1
  34. package/lib/fusion-auth.service.d.ts +13 -5
  35. package/lib/injectionToken.d.ts +3 -0
  36. package/lib/types.d.ts +9 -1
  37. package/package.json +3 -3
  38. package/public-api.d.ts +1 -0
  39. package/sdkcore/CookieHelpers/CookieHelpers.d.ts +11 -0
  40. package/sdkcore/CookieHelpers/index.d.ts +1 -0
  41. package/sdkcore/RedirectHelper/RedirectHelper.d.ts +10 -0
  42. package/sdkcore/RedirectHelper/index.d.ts +1 -0
  43. package/sdkcore/SDKConfig/SDKConfig.d.ts +79 -0
  44. package/sdkcore/SDKConfig/index.d.ts +1 -0
  45. package/sdkcore/SDKContext/SDKContext.d.ts +69 -0
  46. package/sdkcore/SDKContext/index.d.ts +1 -0
  47. package/sdkcore/SDKCore/SDKCore.d.ts +28 -0
  48. package/sdkcore/SDKCore/index.d.ts +1 -0
  49. package/sdkcore/UrlHelper/UrlHelper.d.ts +23 -0
  50. package/sdkcore/UrlHelper/UrlHelperTypes.d.ts +11 -0
  51. package/sdkcore/UrlHelper/index.d.ts +2 -0
  52. package/sdkcore/index.d.ts +5 -0
  53. package/sdkcore/testUtils/index.d.ts +2 -0
  54. package/sdkcore/testUtils/mockLoggedIn.d.ts +5 -0
  55. package/sdkcore/testUtils/mockWindowLocation.d.ts +18 -0
  56. package/esm2022/lib/core.mjs +0 -217
  57. package/lib/core.d.ts +0 -35
@@ -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,175 +47,276 @@ 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 o = this.generateURLSearchParams(t);
66
- s.search = o.toString();
50
+ getAccountManagementUrl() {
51
+ return this.generateUrl('/account/', {
52
+ client_id: this.clientId,
53
+ });
54
+ }
55
+ generateUrl(path, params) {
56
+ const url = new URL(this.serverUrl);
57
+ url.pathname = path;
58
+ if (params) {
59
+ const urlSearchParams = this.generateURLSearchParams(params);
60
+ url.search = urlSearchParams.toString();
67
61
  }
68
- return s;
62
+ return url;
69
63
  }
70
- generateURLSearchParams(e) {
71
- const t = new URLSearchParams();
72
- return (Object.entries(e).forEach(([s, o]) => {
73
- o && t.append(s, o);
74
- }),
75
- t);
64
+ generateURLSearchParams(params) {
65
+ const urlSearchParams = new URLSearchParams();
66
+ Object.entries(params).forEach(([key, value]) => {
67
+ if (value) {
68
+ urlSearchParams.append(key, value);
69
+ }
70
+ });
71
+ return urlSearchParams;
76
72
  }
77
73
  }
78
- class p {
74
+
75
+ /** A class responsible for storing a redirect value in localStorage and cleanup afterward. */
76
+ class RedirectHelper {
79
77
  constructor() {
80
- i(this, 'REDIRECT_VALUE', 'fa-sdk-redirect-value');
78
+ this.REDIRECT_VALUE = 'fa-sdk-redirect-value';
79
+ }
80
+ get storage() {
81
+ try {
82
+ return localStorage;
83
+ }
84
+ catch {
85
+ // fallback for non-browser environments where localStorage is not defined.
86
+ return {
87
+ /* eslint-disable */
88
+ setItem(_key, _value) { },
89
+ getItem(_key) { },
90
+ removeItem(_key) { },
91
+ /* eslint-enable */
92
+ };
93
+ }
81
94
  }
82
- handlePreRedirect(e) {
83
- const t = `${this.generateRandomString()}:${e ?? ''}`;
84
- localStorage.setItem(this.REDIRECT_VALUE, t);
95
+ handlePreRedirect(state) {
96
+ const valueForStorage = `${this.generateRandomString()}:${state ?? ''}`;
97
+ this.storage.setItem(this.REDIRECT_VALUE, valueForStorage);
85
98
  }
86
- handlePostRedirect(e) {
87
- const t = this.stateValue ?? void 0;
88
- e == null || e(t), localStorage.removeItem(this.REDIRECT_VALUE);
99
+ handlePostRedirect(callback) {
100
+ const stateValue = this.stateValue ?? undefined;
101
+ callback?.(stateValue);
102
+ this.storage.removeItem(this.REDIRECT_VALUE);
89
103
  }
90
104
  get didRedirect() {
91
- return !!localStorage.getItem(this.REDIRECT_VALUE);
105
+ return Boolean(this.storage.getItem(this.REDIRECT_VALUE));
92
106
  }
93
107
  get stateValue() {
94
- const e = localStorage.getItem(this.REDIRECT_VALUE);
95
- if (!e)
108
+ const redirectValue = this.storage.getItem(this.REDIRECT_VALUE);
109
+ if (!redirectValue) {
96
110
  return null;
97
- const [, ...t] = e.split(':');
98
- return t.join(':');
111
+ }
112
+ const [, ...stateValue] = redirectValue.split(':');
113
+ return stateValue.join(':');
99
114
  }
100
115
  generateRandomString() {
101
- const e = new Uint32Array(28);
102
- return (window.crypto.getRandomValues(e),
103
- Array.from(e, t => ('0' + t.toString(16)).substring(-2)).join(''));
116
+ const array = new Uint32Array(56 / 2);
117
+ window.crypto.getRandomValues(array);
118
+ return Array.from(array, (n) => ('0' + n.toString(16)).substring(-2)).join('');
104
119
  }
105
120
  }
106
- function m(r = 'app.at_exp') {
107
- const e = document.cookie
121
+
122
+ /**
123
+ * Gets the `app.at_exp` cookie and converts it to milliseconds since epoch.
124
+ * Returns -1 if the cookie is not present.
125
+ * @param cookieName - defaults to `app.at_exp`.
126
+ * @param adapter - SSR frameworks like Nuxt, Next, and angular/ssr will pass in an adapter.
127
+ */
128
+ function getAccessTokenExpirationMoment(cookieName = 'app.at_exp', adapter) {
129
+ if (adapter) {
130
+ return toMilliseconds(adapter.at_exp(cookieName));
131
+ }
132
+ let cookie;
133
+ try {
134
+ // `document` throws a ReferenceError if this runs in a
135
+ // non-browser environment such as an SSR framework like Nuxt or Next.
136
+ cookie = document.cookie;
137
+ }
138
+ catch {
139
+ console.error('Error accessing cookies in fusionauth. If you are using SSR you must configure the SDK with a cookie adapter');
140
+ return -1;
141
+ }
142
+ const expCookie = cookie
108
143
  .split('; ')
109
- .map(s => s.split('='))
110
- .find(([s]) => s === r), t = e == null ? void 0 : e[1];
111
- return t ? parseInt(t) * 1e3 : null;
144
+ .map(c => c.split('='))
145
+ .find(([name]) => name === cookieName);
146
+ const cookieValue = expCookie?.[1];
147
+ return toMilliseconds(cookieValue);
112
148
  }
113
- class U {
114
- constructor(e) {
115
- i(this, 'config');
116
- i(this, 'urlHelper');
117
- i(this, 'redirectHelper', new p());
118
- i(this, 'tokenExpirationTimeout');
119
- (this.config = e),
120
- (this.urlHelper = new g({
121
- serverUrl: e.serverUrl,
122
- clientId: e.clientId,
123
- redirectUri: e.redirectUri,
124
- scope: e.scope,
125
- mePath: e.mePath,
126
- loginPath: e.loginPath,
127
- registerPath: e.registerPath,
128
- logoutPath: e.logoutPath,
129
- tokenRefreshPath: e.tokenRefreshPath,
130
- })),
131
- this.scheduleTokenExpiration();
132
- }
133
- startLogin(e) {
134
- this.redirectHelper.handlePreRedirect(e),
135
- window.location.assign(this.urlHelper.getLoginUrl(e));
136
- }
137
- startRegister(e) {
138
- this.redirectHelper.handlePreRedirect(e),
139
- window.location.assign(this.urlHelper.getRegisterUrl(e));
149
+ function toMilliseconds(seconds) {
150
+ if (!seconds)
151
+ return -1;
152
+ else
153
+ return Number(seconds) * 1000;
154
+ }
155
+
156
+ /** A class containing framework-agnostic SDK methods */
157
+ class SDKCore {
158
+ constructor(config) {
159
+ this.redirectHelper = new RedirectHelper();
160
+ this.config = config;
161
+ this.urlHelper = new UrlHelper({
162
+ serverUrl: config.serverUrl,
163
+ clientId: config.clientId,
164
+ redirectUri: config.redirectUri,
165
+ scope: config.scope,
166
+ mePath: config.mePath,
167
+ loginPath: config.loginPath,
168
+ registerPath: config.registerPath,
169
+ logoutPath: config.logoutPath,
170
+ tokenRefreshPath: config.tokenRefreshPath,
171
+ postLogoutRedirectUri: config.postLogoutRedirectUri,
172
+ });
173
+ this.scheduleTokenExpiration();
174
+ }
175
+ startLogin(state) {
176
+ this.redirectHelper.handlePreRedirect(state);
177
+ window.location.assign(this.urlHelper.getLoginUrl(state));
178
+ }
179
+ startRegister(state) {
180
+ this.redirectHelper.handlePreRedirect(state);
181
+ window.location.assign(this.urlHelper.getRegisterUrl(state));
140
182
  }
141
183
  startLogout() {
142
184
  window.location.assign(this.urlHelper.getLogoutUrl());
143
185
  }
186
+ manageAccount() {
187
+ window.location.assign(this.urlHelper.getAccountManagementUrl());
188
+ }
144
189
  async fetchUserInfo() {
145
- const e = await fetch(this.urlHelper.getMeUrl(), {
190
+ const userInfoResponse = await fetch(this.urlHelper.getMeUrl(), {
146
191
  credentials: 'include',
147
192
  });
148
- if (!e.ok)
149
- throw new Error(`Unable to fetch userInfo in fusionauth. Request failed with status code ${e == null ? void 0 : e.status}`);
150
- return await e.json();
193
+ if (!userInfoResponse.ok) {
194
+ throw new Error(`Unable to fetch userInfo in fusionauth. Request failed with status code ${userInfoResponse?.status}`);
195
+ }
196
+ const userInfo = await userInfoResponse.json();
197
+ return userInfo;
151
198
  }
152
199
  async refreshToken() {
153
- const e = await fetch(this.urlHelper.getTokenRefreshUrl(), {
200
+ const response = await fetch(this.urlHelper.getTokenRefreshUrl(), {
154
201
  method: 'POST',
155
202
  credentials: 'include',
156
203
  headers: {
157
204
  'Content-Type': 'text/plain',
158
205
  },
159
206
  });
160
- if (!(e.status >= 200 && e.status < 300)) {
161
- const t = (await (e == null ? void 0 : e.text())) ||
207
+ if (!(response.status >= 200 && response.status < 300)) {
208
+ const message = (await response?.text()) ||
162
209
  'Error refreshing access token in fusionauth';
163
- throw new Error(t);
210
+ throw new Error(message);
164
211
  }
165
- return this.scheduleTokenExpiration(), e;
212
+ // a successful request means that app_exp was bumped into the future.
213
+ // reschedule the access token expiration event.
214
+ this.scheduleTokenExpiration();
215
+ return response;
166
216
  }
167
217
  initAutoRefresh() {
168
- const e = this.at_exp, t = this.config.autoRefreshSecondsBeforeExpiry ?? 10;
169
- if (!e)
218
+ if (!this.isLoggedIn) {
170
219
  return;
171
- const s = t * 1e3, o = /* @__PURE__ */ new Date().getTime(), h = e - s, l = Math.max(h - o, 0);
220
+ }
221
+ const secondsBeforeRefresh = this.config.autoRefreshSecondsBeforeExpiry ?? 10;
222
+ const millisecondsBeforeRefresh = secondsBeforeRefresh * 1000;
223
+ const now = new Date().getTime();
224
+ const refreshTime = this.at_exp - millisecondsBeforeRefresh;
225
+ const timeTillRefresh = Math.max(refreshTime - now, 0);
172
226
  return setTimeout(async () => {
173
- let n, a;
174
227
  try {
175
- await this.refreshToken(), this.initAutoRefresh();
228
+ await this.refreshToken();
229
+ this.initAutoRefresh();
176
230
  }
177
- catch (c) {
178
- (a = (n = this.config).onAutoRefreshFailure) == null || a.call(n, c);
231
+ catch (error) {
232
+ this.config.onAutoRefreshFailure?.(error);
179
233
  }
180
- }, l);
234
+ }, timeTillRefresh);
181
235
  }
182
- handlePostRedirect(e) {
183
- this.isLoggedIn &&
184
- this.redirectHelper.didRedirect &&
185
- this.redirectHelper.handlePostRedirect(e);
236
+ handlePostRedirect(callback) {
237
+ if (this.isLoggedIn && this.redirectHelper.didRedirect) {
238
+ this.redirectHelper.handlePostRedirect(callback);
239
+ }
186
240
  }
187
241
  get isLoggedIn() {
188
- return this.at_exp
189
- ? this.at_exp > /* @__PURE__ */ new Date().getTime()
190
- : !1;
242
+ return this.at_exp > new Date().getTime();
191
243
  }
192
244
  /** The moment of access token expiration in milliseconds since epoch. */
193
245
  get at_exp() {
194
- return m(this.config.accessTokenExpireCookieName);
246
+ return getAccessTokenExpirationMoment(this.config.accessTokenExpireCookieName, this.config.cookieAdapter);
195
247
  }
196
- /** Schedules `onTokenExpiration` at moment of access token expiration. */
248
+ /**
249
+ * Schedules `onTokenExpiration` at moment of access token expiration.
250
+ * SDKCore is not necessarily reactive like React, Angular, and Vue.
251
+ * so `onTokenExpiration` is for reactive frameworks to hook in and perform actions as on token expiration.
252
+ */
197
253
  scheduleTokenExpiration() {
198
254
  clearTimeout(this.tokenExpirationTimeout);
199
- const e = this.at_exp ?? -1, t = /* @__PURE__ */ new Date().getTime(), s = e - t;
200
- s > 0 &&
201
- (this.tokenExpirationTimeout = setTimeout(this.config.onTokenExpiration, s));
255
+ const now = new Date().getTime();
256
+ const millisecondsTillExpiration = this.at_exp - now;
257
+ if (millisecondsTillExpiration > 0) {
258
+ this.tokenExpirationTimeout = setTimeout(this.config.onTokenExpiration, millisecondsTillExpiration);
259
+ }
202
260
  }
203
261
  }
204
- function P() {
205
- const r = /* @__PURE__ */ new Date();
206
- r.setHours(r.getHours() + 1);
207
- const e = r.getTime() / 1e3;
208
- document.cookie = `app.at_exp=${e}`;
262
+
263
+ /** Sets `app.at_exp` moment cookie so the user will be logged in for 1 hour. */
264
+ function mockIsLoggedIn() {
265
+ const expirationMoment = new Date();
266
+ expirationMoment.setHours(expirationMoment.getHours() + 1);
267
+ const oneHourInTheFutureInMilliseconds = expirationMoment.getTime() / 1000;
268
+ document.cookie = `app.at_exp=${oneHourInTheFutureInMilliseconds}`;
209
269
  }
210
- function f() {
211
- document.cookie = 'app.at_exp=;expires=Thu, 01 Jan 1970 00:00:00 GMT';
270
+ /** Removes the `app.at_exp` cookie. */
271
+ function removeAt_expCookie() {
272
+ document.cookie = 'app.at_exp' + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT';
212
273
  }
213
- function w(r) {
214
- const e = {
274
+
275
+ function mockWindowLocation(vi) {
276
+ const mockedLocation = {
215
277
  ...window.location,
216
- assign: r.fn(),
278
+ assign: vi.fn(),
217
279
  };
218
- return r.spyOn(window, 'location', 'get').mockReturnValue(e), e;
280
+ vi.spyOn(window, 'location', 'get').mockReturnValue(mockedLocation);
281
+ return mockedLocation;
219
282
  }
220
283
 
284
+ /** An adapter class that supports accessing cookies with SSR */
285
+ class SSRCookieAdapter {
286
+ constructor(isBrowser) {
287
+ this.isBrowser = isBrowser;
288
+ }
289
+ at_exp(cookieName = 'app.at_exp') {
290
+ if (!this.isBrowser) {
291
+ return;
292
+ }
293
+ try {
294
+ const expCookie = document.cookie
295
+ .split('; ')
296
+ .map(c => c.split('='))
297
+ .find(([name]) => name === cookieName);
298
+ return expCookie?.[1];
299
+ }
300
+ catch (error) {
301
+ console.error('Error within the SSRCookieAdapter: ', error);
302
+ return -1;
303
+ }
304
+ }
305
+ }
306
+
307
+ const FUSIONAUTH_SERVICE_CONFIG = new InjectionToken('FUSIONAUTH_SERVICE_CONFIG');
308
+
221
309
  /**
222
310
  * Service class to use with FusionAuth backend endpoints.
223
311
  */
224
312
  class FusionAuthService {
225
- constructor(config) {
226
- this.core = new U({
313
+ constructor(config, platformId) {
314
+ this.core = new SDKCore({
227
315
  ...config,
228
316
  onTokenExpiration: () => {
229
317
  this.isLoggedInSubject.next(false);
230
318
  },
319
+ cookieAdapter: new SSRCookieAdapter(isPlatformBrowser(platformId)),
231
320
  });
232
321
  this.isLoggedInSubject = new BehaviorSubject(this.core.isLoggedIn);
233
322
  this.isLoggedIn$ = this.isLoggedInSubject.asObservable();
@@ -305,7 +394,28 @@ class FusionAuthService {
305
394
  logout() {
306
395
  this.core.startLogout();
307
396
  }
397
+ /**
398
+ * Redirects to [self service account management](https://fusionauth.io/docs/lifecycle/manage-users/account-management/)
399
+ * Self service account management is only available in FusionAuth paid plans.
400
+ */
401
+ manageAccount() {
402
+ this.core.manageAccount();
403
+ }
404
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthService, deps: [{ token: FUSIONAUTH_SERVICE_CONFIG }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
405
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthService, providedIn: 'root' }); }
308
406
  }
407
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthService, decorators: [{
408
+ type: Injectable,
409
+ args: [{
410
+ providedIn: 'root',
411
+ }]
412
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
413
+ type: Inject,
414
+ args: [FUSIONAUTH_SERVICE_CONFIG]
415
+ }] }, { type: Object, decorators: [{
416
+ type: Inject,
417
+ args: [PLATFORM_ID]
418
+ }] }] });
309
419
 
310
420
  class FusionAuthLoginButtonComponent {
311
421
  constructor(fusionAuth) {
@@ -314,10 +424,10 @@ class FusionAuthLoginButtonComponent {
314
424
  login() {
315
425
  this.fusionAuth.startLogin(this.state);
316
426
  }
317
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthLoginButtonComponent, deps: [{ token: FusionAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
318
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.1", type: FusionAuthLoginButtonComponent, selector: "fa-login", inputs: { state: "state" }, ngImport: i0, template: "<button class=\"fa-button\" (click)=\"login()\">\n <span>Login</span>\n</button>\n", styles: [".fa-button{padding:16px 16px 13px;border-radius:8px;background-color:#083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:18px;font-weight:600;text-align:center;color:#fff;width:400px}.fa-button:hover{cursor:pointer}\n"] }); }
427
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthLoginButtonComponent, deps: [{ token: FusionAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
428
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: FusionAuthLoginButtonComponent, selector: "fa-login", inputs: { state: "state" }, ngImport: i0, template: "<button class=\"fa-button\" (click)=\"login()\">\n <span>Login</span>\n</button>\n", styles: [".fa-button{padding:16px 16px 13px;border-radius:8px;background-color:#083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:18px;font-weight:600;text-align:center;color:#fff;width:400px}.fa-button:hover{cursor:pointer}\n"] }); }
319
429
  }
320
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthLoginButtonComponent, decorators: [{
430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthLoginButtonComponent, decorators: [{
321
431
  type: Component,
322
432
  args: [{ selector: 'fa-login', template: "<button class=\"fa-button\" (click)=\"login()\">\n <span>Login</span>\n</button>\n", styles: [".fa-button{padding:16px 16px 13px;border-radius:8px;background-color:#083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:18px;font-weight:600;text-align:center;color:#fff;width:400px}.fa-button:hover{cursor:pointer}\n"] }]
323
433
  }], ctorParameters: () => [{ type: FusionAuthService }], propDecorators: { state: [{
@@ -331,10 +441,10 @@ class FusionAuthLogoutButtonComponent {
331
441
  logout() {
332
442
  this.fusionAuth.logout();
333
443
  }
334
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthLogoutButtonComponent, deps: [{ token: FusionAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
335
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.1", type: FusionAuthLogoutButtonComponent, selector: "fa-logout", ngImport: i0, template: "<button class=\"fa-logout-button\" (click)=\"logout()\">\n <span>logout</span>\n</button>\n", styles: [".fa-logout-button{padding:7px 13px;border-radius:3px;display:block;border:solid 1px #083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:12px;text-align:center;color:#083b94}.fa-logout-button:hover{cursor:pointer}\n"] }); }
444
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthLogoutButtonComponent, deps: [{ token: FusionAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
445
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: FusionAuthLogoutButtonComponent, selector: "fa-logout", ngImport: i0, template: "<button class=\"fa-logout-button\" (click)=\"logout()\">\n <span>logout</span>\n</button>\n", styles: [".fa-logout-button{padding:7px 13px;border-radius:3px;display:block;border:solid 1px #083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:12px;text-align:center;color:#083b94}.fa-logout-button:hover{cursor:pointer}\n"] }); }
336
446
  }
337
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthLogoutButtonComponent, decorators: [{
447
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthLogoutButtonComponent, decorators: [{
338
448
  type: Component,
339
449
  args: [{ selector: 'fa-logout', template: "<button class=\"fa-logout-button\" (click)=\"logout()\">\n <span>logout</span>\n</button>\n", styles: [".fa-logout-button{padding:7px 13px;border-radius:3px;display:block;border:solid 1px #083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:12px;text-align:center;color:#083b94}.fa-logout-button:hover{cursor:pointer}\n"] }]
340
450
  }], ctorParameters: () => [{ type: FusionAuthService }] });
@@ -346,49 +456,66 @@ class FusionAuthRegisterButtonComponent {
346
456
  register() {
347
457
  this.fusionAuth.startRegistration(this.state);
348
458
  }
349
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthRegisterButtonComponent, deps: [{ token: FusionAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
350
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.1", type: FusionAuthRegisterButtonComponent, selector: "fa-register", inputs: { state: "state" }, ngImport: i0, template: "<button class=\"fa-button\" (click)=\"register()\">\n <span>Register Now</span>\n</button>\n", styles: [".fa-button{padding:16px 16px 13px;border-radius:8px;background-color:#083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:18px;font-weight:600;text-align:center;color:#fff;width:400px}.fa-button:hover{cursor:pointer}\n"] }); }
459
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthRegisterButtonComponent, deps: [{ token: FusionAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
460
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: FusionAuthRegisterButtonComponent, selector: "fa-register", inputs: { state: "state" }, ngImport: i0, template: "<button class=\"fa-button\" (click)=\"register()\">\n <span>Register Now</span>\n</button>\n", styles: [".fa-button{padding:16px 16px 13px;border-radius:8px;background-color:#083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:18px;font-weight:600;text-align:center;color:#fff;width:400px}.fa-button:hover{cursor:pointer}\n"] }); }
351
461
  }
352
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthRegisterButtonComponent, decorators: [{
462
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthRegisterButtonComponent, decorators: [{
353
463
  type: Component,
354
464
  args: [{ selector: 'fa-register', template: "<button class=\"fa-button\" (click)=\"register()\">\n <span>Register Now</span>\n</button>\n", styles: [".fa-button{padding:16px 16px 13px;border-radius:8px;background-color:#083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:18px;font-weight:600;text-align:center;color:#fff;width:400px}.fa-button:hover{cursor:pointer}\n"] }]
355
465
  }], ctorParameters: () => [{ type: FusionAuthService }], propDecorators: { state: [{
356
466
  type: Input
357
467
  }] } });
358
468
 
469
+ class FusionAuthAccountButtonComponent {
470
+ constructor(fusionAuth) {
471
+ this.fusionAuth = fusionAuth;
472
+ }
473
+ manageAccount() {
474
+ this.fusionAuth.manageAccount();
475
+ }
476
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthAccountButtonComponent, deps: [{ token: FusionAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
477
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: FusionAuthAccountButtonComponent, selector: "fa-account", ngImport: i0, template: "<button class=\"fa-button\" (click)=\"manageAccount()\">\n <span>manage account</span>\n</button>\n", styles: [".fa-button{padding:16px 16px 13px;border-radius:8px;background-color:#083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:18px;font-weight:600;text-align:center;color:#fff;width:400px}.fa-button:hover{cursor:pointer}\n"] }); }
478
+ }
479
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthAccountButtonComponent, decorators: [{
480
+ type: Component,
481
+ args: [{ selector: 'fa-account', template: "<button class=\"fa-button\" (click)=\"manageAccount()\">\n <span>manage account</span>\n</button>\n", styles: [".fa-button{padding:16px 16px 13px;border-radius:8px;background-color:#083b94;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",Segoe UI Symbol;font-size:18px;font-weight:600;text-align:center;color:#fff;width:400px}.fa-button:hover{cursor:pointer}\n"] }]
482
+ }], ctorParameters: () => [{ type: FusionAuthService }] });
483
+
359
484
  class FusionAuthModule {
360
485
  static forRoot(fusionAuthConfig) {
361
486
  return {
362
487
  ngModule: FusionAuthModule,
363
488
  providers: [
364
- {
365
- provide: FusionAuthService,
366
- useValue: new FusionAuthService(fusionAuthConfig),
367
- },
489
+ { provide: FUSIONAUTH_SERVICE_CONFIG, useValue: fusionAuthConfig },
490
+ FusionAuthService,
368
491
  ],
369
492
  };
370
493
  }
371
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
372
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthModule, declarations: [FusionAuthLoginButtonComponent,
494
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
495
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthModule, declarations: [FusionAuthLoginButtonComponent,
373
496
  FusionAuthLogoutButtonComponent,
374
- FusionAuthRegisterButtonComponent], exports: [FusionAuthLoginButtonComponent,
497
+ FusionAuthRegisterButtonComponent,
498
+ FusionAuthAccountButtonComponent], exports: [FusionAuthLoginButtonComponent,
375
499
  FusionAuthLogoutButtonComponent,
376
- FusionAuthRegisterButtonComponent] }); }
377
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthModule }); }
500
+ FusionAuthRegisterButtonComponent,
501
+ FusionAuthAccountButtonComponent] }); }
502
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthModule }); }
378
503
  }
379
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.1", ngImport: i0, type: FusionAuthModule, decorators: [{
504
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: FusionAuthModule, decorators: [{
380
505
  type: NgModule,
381
506
  args: [{
382
507
  declarations: [
383
508
  FusionAuthLoginButtonComponent,
384
509
  FusionAuthLogoutButtonComponent,
385
510
  FusionAuthRegisterButtonComponent,
511
+ FusionAuthAccountButtonComponent,
386
512
  ],
387
513
  imports: [],
388
514
  exports: [
389
515
  FusionAuthLoginButtonComponent,
390
516
  FusionAuthLogoutButtonComponent,
391
517
  FusionAuthRegisterButtonComponent,
518
+ FusionAuthAccountButtonComponent,
392
519
  ],
393
520
  }]
394
521
  }] });
@@ -401,5 +528,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.1", ngImpor
401
528
  * Generated bundle index. Do not edit.
402
529
  */
403
530
 
404
- export { FusionAuthLoginButtonComponent, FusionAuthLogoutButtonComponent, FusionAuthModule, FusionAuthRegisterButtonComponent, FusionAuthService };
531
+ export { FusionAuthAccountButtonComponent, FusionAuthLoginButtonComponent, FusionAuthLogoutButtonComponent, FusionAuthModule, FusionAuthRegisterButtonComponent, FusionAuthService };
405
532
  //# sourceMappingURL=fusionauth-angular-sdk.mjs.map