zavadil-ts-common 1.2.39 → 1.2.41

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.
@@ -1,30 +1,23 @@
1
1
  import { OAuthTokenManager } from "./OAuthTokenManager";
2
2
  import { RestClient } from "../client";
3
3
  import { IdTokenPayload } from "./OAuthRestClient";
4
+ import { OAuthIdTokenProvider } from "./tokenprovider/OAuthIdTokenProvider";
4
5
  export type ServerOAuthInfoPayload = {
5
6
  debugMode?: boolean;
6
7
  targetAudience: string;
7
8
  oauthServerUrl: string;
8
9
  version: string;
9
10
  };
10
- export declare class RestClientWithOAuth extends RestClient {
11
- private tokenName;
11
+ export declare class RestClientWithOAuth extends RestClient implements OAuthIdTokenProvider {
12
12
  private insecureClient;
13
+ private freshIdTokenProvider;
13
14
  private tokenManager;
14
15
  private serverInfo;
15
16
  private defaultPrivilege;
16
- private redirecting?;
17
- constructor(url: string, defaultPrivilege?: string);
18
- isRedirecting(): boolean;
19
- redirectingTo(): string;
20
- redirectTo(url: string): Promise<any>;
21
- initializeIdToken(): Promise<any>;
17
+ constructor(url: string, freshIdTokenProvider?: OAuthIdTokenProvider, defaultPrivilege?: string);
18
+ getIdToken(): Promise<IdTokenPayload>;
22
19
  /**
23
- * Attempt to get ID token from URL or storage, redirect to login page when not successful
24
- */
25
- redirectToLogin(): Promise<any>;
26
- /**
27
- * Attempt to get ID token from URL or storage, redirect to login page when not successful
20
+ * Attempt to get ID token from token manager
28
21
  */
29
22
  initialize(): Promise<any>;
30
23
  logout(): Promise<any>;
@@ -33,23 +26,11 @@ export declare class RestClientWithOAuth extends RestClient {
33
26
  * @param url
34
27
  */
35
28
  getPrivilege(url: string): string;
36
- deleteIdTokenFromUrl(): string;
37
- getIdTokenFromUrl(): string | null;
38
- getIdTokenFromLocalStorage(): IdTokenPayload | null | undefined;
39
- saveIdTokenToLocalStorage(token: IdTokenPayload | null): void;
40
- addIdTokenChangedHandler(handler: () => any): void;
41
- removeIdTokenChangedHandler(handler: () => any): void;
42
29
  private getServerInfoInternal;
43
30
  getServerInfo(): Promise<ServerOAuthInfoPayload>;
44
- private getTokenManagerInternal;
31
+ protected getTokenManagerInternal(): Promise<OAuthTokenManager>;
45
32
  getTokenManager(): Promise<OAuthTokenManager>;
46
33
  login(login: string, password: string): Promise<any>;
47
34
  setIdToken(token: IdTokenPayload): Promise<any>;
48
- setIdTokenRaw(token: string): Promise<any>;
49
35
  getHeaders(endpoint: string): Promise<Headers>;
50
- /**
51
- * Try to obtain access token, then return if everything is okay.
52
- * This is basically only used when initializing and trying to determine whether we need to redirect user to login page
53
- */
54
- checkAccessToken(privilege?: string): Promise<any>;
55
36
  }
@@ -0,0 +1,13 @@
1
+ import { OAuthIdTokenProvider } from "./OAuthIdTokenProvider";
2
+ import { IdTokenPayload } from "../OAuthRestClient";
3
+ import { IdTokenProviderLogin } from "./IdTokenProviderLogin";
4
+ import { RestClientWithOAuth } from "../RestClientWithOAuth";
5
+ import { IdTokenProviderUrl } from "./IdTokenProviderUrl";
6
+ import { IdTokenProviderStorage } from "./IdTokenProviderStorage";
7
+ export declare class IdTokenProviderDefault implements OAuthIdTokenProvider {
8
+ login: IdTokenProviderLogin;
9
+ url: IdTokenProviderUrl;
10
+ storage: IdTokenProviderStorage;
11
+ constructor(client: RestClientWithOAuth, tokenStorageKey?: string, tokenUrlName?: string);
12
+ getIdToken(): Promise<IdTokenPayload>;
13
+ }
@@ -0,0 +1,14 @@
1
+ import { OAuthIdTokenProvider } from "./OAuthIdTokenProvider";
2
+ import { IdTokenPayload } from "../OAuthRestClient";
3
+ import { RedirectionProvider } from "./RedirectionProvider";
4
+ import { RestClientWithOAuth } from "../RestClientWithOAuth";
5
+ export declare class IdTokenProviderLogin extends RedirectionProvider implements OAuthIdTokenProvider {
6
+ client: RestClientWithOAuth;
7
+ tokenQueryName: string;
8
+ constructor(client: RestClientWithOAuth, tokenQueryName?: string);
9
+ /**
10
+ * Attempt to get ID token from URL or storage, redirect to login page when not successful
11
+ */
12
+ redirectToLogin(): Promise<any>;
13
+ getIdToken(): Promise<IdTokenPayload>;
14
+ }
@@ -0,0 +1,9 @@
1
+ import { OAuthIdTokenProvider } from "./OAuthIdTokenProvider";
2
+ import { IdTokenPayload } from "../OAuthRestClient";
3
+ export declare class IdTokenProviderStorage implements OAuthIdTokenProvider {
4
+ key: string;
5
+ constructor(storageKey?: string);
6
+ saveIdTokenToLocalStorage(token: IdTokenPayload | null): void;
7
+ getIdTokenFromLocalStorage(): IdTokenPayload | null | undefined;
8
+ getIdToken(): Promise<IdTokenPayload>;
9
+ }
@@ -0,0 +1,10 @@
1
+ import { OAuthIdTokenProvider } from "./OAuthIdTokenProvider";
2
+ import { IdTokenPayload } from "../OAuthRestClient";
3
+ import { RestClientWithOAuth } from "../RestClientWithOAuth";
4
+ export declare class IdTokenProviderUrl implements OAuthIdTokenProvider {
5
+ client: RestClientWithOAuth;
6
+ tokenQueryName: string;
7
+ constructor(client: RestClientWithOAuth, tokenQueryName?: string);
8
+ getIdTokenFromUrl(): string | null;
9
+ getIdToken(): Promise<IdTokenPayload>;
10
+ }
@@ -0,0 +1,4 @@
1
+ import { IdTokenPayload } from "../OAuthRestClient";
2
+ export interface OAuthIdTokenProvider {
3
+ getIdToken(): Promise<IdTokenPayload>;
4
+ }
@@ -0,0 +1,6 @@
1
+ export declare class RedirectionProvider {
2
+ private redirecting?;
3
+ redirectTo(url: string): Promise<any>;
4
+ isRedirecting(): boolean;
5
+ redirectingTo(): string;
6
+ }
@@ -0,0 +1,5 @@
1
+ export default class UrlUtil {
2
+ static deleteParamFromUrl(url: string, paramName: string): string;
3
+ static extractParamFromUrl(url: string, name: string): string | null;
4
+ static paramExistsInUrl(url: string, name: string): boolean;
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zavadil-ts-common",
3
- "version": "1.2.39",
3
+ "version": "1.2.41",
4
4
  "description": "Common types and components for Typescript UI apps.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -1,11 +1,12 @@
1
1
  import {AccessTokenPayload, IdTokenPayload, OAuthRestClient} from "./OAuthRestClient";
2
2
  import {EventManager} from "../component";
3
3
  import {StringUtil} from "../util";
4
+ import {OAuthIdTokenProvider} from "./tokenprovider/OAuthIdTokenProvider";
4
5
 
5
6
  /**
6
7
  * Manages refresh of id and access tokens.
7
8
  */
8
- export class OAuthTokenManager {
9
+ export class OAuthTokenManager implements OAuthIdTokenProvider {
9
10
 
10
11
  private eventManager: EventManager = new EventManager();
11
12
 
@@ -15,9 +16,12 @@ export class OAuthTokenManager {
15
16
 
16
17
  idToken?: IdTokenPayload;
17
18
 
19
+ freshIdTokenProvider: OAuthIdTokenProvider;
20
+
18
21
  accessTokens: Map<string, AccessTokenPayload>;
19
22
 
20
- constructor(oAuthServerBaseUrl: string, targetAudience: string) {
23
+ constructor(oAuthServerBaseUrl: string, targetAudience: string, freshIdTokenProvider: OAuthIdTokenProvider) {
24
+ this.freshIdTokenProvider = freshIdTokenProvider;
21
25
  this.audience = targetAudience;
22
26
  this.oAuthServer = new OAuthRestClient(oAuthServerBaseUrl);
23
27
  this.accessTokens = new Map<string, AccessTokenPayload>();
@@ -65,21 +69,41 @@ export class OAuthTokenManager {
65
69
  this.accessTokens.clear();
66
70
  }
67
71
 
68
- getIdToken(): Promise<string> {
72
+ /**
73
+ * Get stored id token or ask the provider, this will trigger redirect to login screen in case of the default provider
74
+ */
75
+ getIdTokenInternal(): Promise<IdTokenPayload> {
69
76
  if (this.idToken === undefined || !this.hasValidIdToken()) {
70
- return Promise.reject("No valid ID token!");
77
+ return this.freshIdTokenProvider.getIdToken();
71
78
  }
72
- if (this.isTokenReadyForRefresh(this.idToken.issuedAt, this.idToken.expires)) {
73
- return this.oAuthServer
74
- .refreshIdToken({idToken: this.idToken.token})
75
- .then(
76
- (t) => {
77
- this.setIdToken(t);
78
- return t.token;
79
+ return Promise.resolve(this.idToken);
80
+ }
81
+
82
+ /**
83
+ * Get id token, refresh it if needed
84
+ */
85
+ getIdToken(): Promise<IdTokenPayload> {
86
+ return this.getIdTokenInternal()
87
+ .then(
88
+ (t: IdTokenPayload) => {
89
+ if (this.isTokenReadyForRefresh(t.issuedAt, t.expires)) {
90
+ return this.oAuthServer
91
+ .refreshIdToken({idToken: t.token})
92
+ .then(
93
+ (t) => {
94
+ this.setIdToken(t);
95
+ return t;
96
+ }
97
+ );
79
98
  }
80
- );
81
- }
82
- return Promise.resolve(this.idToken.token);
99
+ this.setIdToken(t);
100
+ return Promise.resolve(t);
101
+ }
102
+ );
103
+ }
104
+
105
+ getIdTokenRaw(): Promise<string> {
106
+ return this.getIdToken().then(t => t.token);
83
107
  }
84
108
 
85
109
  setIdToken(token?: IdTokenPayload) {
@@ -90,22 +114,19 @@ export class OAuthTokenManager {
90
114
  this.eventManager.triggerEvent('id-token-changed', token);
91
115
  }
92
116
 
93
- verifyIdToken(token: string): Promise<any> {
94
- return this.oAuthServer.verifyIdToken(token)
95
- .then((t) => this.setIdToken(t));
117
+ verifyIdToken(token: string): Promise<IdTokenPayload> {
118
+ return this.oAuthServer.verifyIdToken(token);
96
119
  }
97
120
 
98
121
  login(login: string, password: string): Promise<any> {
99
122
  this.reset();
100
- return this.oAuthServer.requestIdTokenFromLogin({login: login, password: password, targetAudience: this.audience})
101
- .then(
102
- (t) => {
103
- this.setIdToken(t);
104
- })
123
+ return this.oAuthServer
124
+ .requestIdTokenFromLogin({login: login, password: password, targetAudience: this.audience})
125
+ .then((t) => this.setIdToken(t));
105
126
  }
106
127
 
107
128
  private getAccessTokenInternal(privilege: string): Promise<AccessTokenPayload> {
108
- return this.getIdToken()
129
+ return this.getIdTokenRaw()
109
130
  .then(
110
131
  (idToken: string) => this.oAuthServer
111
132
  .requestAccessToken({idToken: idToken, targetAudience: this.audience, privilege: privilege})
@@ -1,8 +1,9 @@
1
1
  import {OAuthTokenManager} from "./OAuthTokenManager";
2
2
  import {RestClient} from "../client";
3
- import {IdTokenPayload} from "./OAuthRestClient";
3
+ import {IdTokenPayload, TokenResponsePayloadBase} from "./OAuthRestClient";
4
4
  import {LazyAsync} from "../cache";
5
- import {StringUtil, JsonUtil} from "../util";
5
+ import {OAuthIdTokenProvider} from "./tokenprovider/OAuthIdTokenProvider";
6
+ import {IdTokenProviderDefault} from "./tokenprovider/IdTokenProviderDefault";
6
7
 
7
8
  export type ServerOAuthInfoPayload = {
8
9
  debugMode?: boolean;
@@ -11,22 +12,22 @@ export type ServerOAuthInfoPayload = {
11
12
  version: string;
12
13
  }
13
14
 
14
- export class RestClientWithOAuth extends RestClient {
15
-
16
- private tokenName = 'token';
15
+ export class RestClientWithOAuth extends RestClient implements OAuthIdTokenProvider {
17
16
 
18
17
  private insecureClient: RestClient;
19
18
 
19
+ private freshIdTokenProvider: OAuthIdTokenProvider;
20
+
20
21
  private tokenManager: LazyAsync<OAuthTokenManager>;
21
22
 
22
23
  private serverInfo: LazyAsync<ServerOAuthInfoPayload>;
23
24
 
24
25
  private defaultPrivilege: string;
25
26
 
26
- private redirecting?: string;
27
-
28
- constructor(url: string, defaultPrivilege: string = '*') {
27
+ constructor(url: string, freshIdTokenProvider?: OAuthIdTokenProvider, defaultPrivilege: string = '*') {
29
28
  super(url);
29
+
30
+ this.freshIdTokenProvider = freshIdTokenProvider || new IdTokenProviderDefault(this);
30
31
  this.defaultPrivilege = defaultPrivilege;
31
32
 
32
33
  // rest client without OAuth headers
@@ -36,65 +37,15 @@ export class RestClientWithOAuth extends RestClient {
36
37
  this.tokenManager = new LazyAsync<OAuthTokenManager>(() => this.getTokenManagerInternal());
37
38
  }
38
39
 
39
- isRedirecting(): boolean {
40
- return StringUtil.notBlank(this.redirecting);
41
- }
42
-
43
- redirectingTo(): string {
44
- return StringUtil.getNonEmpty(this.redirecting);
45
- }
46
-
47
- redirectTo(url: string): Promise<any> {
48
- this.redirecting = url;
49
- document.location.href = url;
50
- return Promise.reject(`Redirecting to ${url}`);
51
- }
52
-
53
- initializeIdToken(): Promise<any> {
54
- const urlToken = this.getIdTokenFromUrl();
55
- if (urlToken !== null) {
56
- return this
57
- .setIdTokenRaw(urlToken)
58
- .then(
59
- () => this.redirectTo(this.deleteIdTokenFromUrl())
60
- );
61
- } else {
62
- const storageToken = this.getIdTokenFromLocalStorage();
63
- if (storageToken) return this.setIdToken(storageToken);
64
- }
65
- return Promise.reject("No valid ID token!");
66
- }
67
-
68
- /**
69
- * Attempt to get ID token from URL or storage, redirect to login page when not successful
70
- */
71
- redirectToLogin(): Promise<any> {
72
- if (this.isRedirecting()) return Promise.reject("Already redirecting!");
73
- return this.getServerInfo().then(
74
- (si) => {
75
- const location = `${si.oauthServerUrl}/login?app_name=${si.targetAudience}&redirect_url=${this.deleteIdTokenFromUrl()}`;
76
- return this.redirectTo(location);
77
- }
78
- ).catch((err) => {
79
- console.error('Redirection failed: OAuth info not fetched:', err);
80
- return Promise.reject(err);
81
- });
82
- }
40
+ getIdToken(): Promise<IdTokenPayload> {
41
+ return this.getTokenManager().then(t => t.getIdToken());
42
+ }
83
43
 
84
44
  /**
85
- * Attempt to get ID token from URL or storage, redirect to login page when not successful
45
+ * Attempt to get ID token from token manager
86
46
  */
87
47
  initialize(): Promise<any> {
88
- return this.initializeIdToken()
89
- .then(() => {
90
- if (!this.isRedirecting()) return this.checkAccessToken();
91
- })
92
- .catch(
93
- (reason) => {
94
- console.log('OAuth initialization failed:', reason);
95
- return this.redirectToLogin();
96
- }
97
- );
48
+ return this.getIdToken();
98
49
  }
99
50
 
100
51
  logout(): Promise<any> {
@@ -111,38 +62,6 @@ export class RestClientWithOAuth extends RestClient {
111
62
  return this.defaultPrivilege;
112
63
  }
113
64
 
114
- deleteIdTokenFromUrl(): string {
115
- const url = new URL(document.location.toString());
116
- url.searchParams.delete(this.tokenName);
117
- return StringUtil.trimTrailingSlashes(url.toString());
118
- }
119
-
120
- getIdTokenFromUrl(): string | null {
121
- const up = new URLSearchParams(document.location.search);
122
- return up.get(this.tokenName);
123
- }
124
-
125
- getIdTokenFromLocalStorage(): IdTokenPayload | null | undefined {
126
- return JsonUtil.parse(localStorage.getItem('id-token'));
127
- }
128
-
129
- saveIdTokenToLocalStorage(token: IdTokenPayload | null) {
130
- const raw = token ? JSON.stringify(token) : null;
131
- if (raw === null) {
132
- localStorage.removeItem('id-token');
133
- return;
134
- }
135
- localStorage.setItem('id-token', raw);
136
- }
137
-
138
- addIdTokenChangedHandler(handler: () => any) {
139
- this.getTokenManager().then((m) => m.addIdTokenChangedHandler(handler));
140
- }
141
-
142
- removeIdTokenChangedHandler(handler: () => any) {
143
- this.getTokenManager().then((m) => m.removeIdTokenChangedHandler(handler));
144
- }
145
-
146
65
  private getServerInfoInternal(): Promise<ServerOAuthInfoPayload> {
147
66
  return this.insecureClient.getJson('status/oauth/info');
148
67
  }
@@ -151,15 +70,10 @@ export class RestClientWithOAuth extends RestClient {
151
70
  return this.serverInfo.get();
152
71
  }
153
72
 
154
- private getTokenManagerInternal(): Promise<OAuthTokenManager> {
155
- return this.getServerInfo()
156
- .then(
157
- (info) => {
158
- const tm = new OAuthTokenManager(info.oauthServerUrl, info.targetAudience);
159
- tm.addIdTokenChangedHandler((t: IdTokenPayload) => this.saveIdTokenToLocalStorage(t));
160
- return tm;
161
- }
162
- );
73
+ protected getTokenManagerInternal(): Promise<OAuthTokenManager> {
74
+ return this
75
+ .getServerInfo()
76
+ .then((info) => new OAuthTokenManager(info.oauthServerUrl, info.targetAudience, this.freshIdTokenProvider));
163
77
  }
164
78
 
165
79
  getTokenManager(): Promise<OAuthTokenManager> {
@@ -175,10 +89,6 @@ export class RestClientWithOAuth extends RestClient {
175
89
  .then((m) => m.setIdToken(token));
176
90
  }
177
91
 
178
- setIdTokenRaw(token: string): Promise<any> {
179
- return this.getTokenManager().then(m => m.verifyIdToken(token))
180
- }
181
-
182
92
  getHeaders(endpoint: string): Promise<Headers> {
183
93
  return this.getTokenManager()
184
94
  .then(tm => tm.getAccessToken(this.getPrivilege(endpoint)))
@@ -193,14 +103,4 @@ export class RestClientWithOAuth extends RestClient {
193
103
  );
194
104
  }
195
105
 
196
- /**
197
- * Try to obtain access token, then return if everything is okay.
198
- * This is basically only used when initializing and trying to determine whether we need to redirect user to login page
199
- */
200
- checkAccessToken(privilege?: string): Promise<any> {
201
- return this.getTokenManager()
202
- .then(tm => tm.getAccessToken(StringUtil.getNonEmpty(privilege, this.defaultPrivilege)))
203
- .catch((e) => Promise.reject(`Access token check failed: ${e}`));
204
- }
205
-
206
106
  }
@@ -0,0 +1,44 @@
1
+ import {OAuthIdTokenProvider} from "./OAuthIdTokenProvider";
2
+ import {IdTokenPayload} from "../OAuthRestClient";
3
+ import {IdTokenProviderLogin} from "./IdTokenProviderLogin";
4
+ import {RestClientWithOAuth} from "../RestClientWithOAuth";
5
+ import { IdTokenProviderUrl } from "./IdTokenProviderUrl";
6
+ import {IdTokenProviderStorage} from "./IdTokenProviderStorage";
7
+
8
+ export class IdTokenProviderDefault implements OAuthIdTokenProvider {
9
+
10
+ login: IdTokenProviderLogin;
11
+
12
+ url: IdTokenProviderUrl;
13
+
14
+ storage: IdTokenProviderStorage;
15
+
16
+ constructor(client: RestClientWithOAuth, tokenStorageKey?: string, tokenUrlName?: string) {
17
+ this.login = new IdTokenProviderLogin(client, tokenUrlName);
18
+ this.url = new IdTokenProviderUrl(client, tokenUrlName);
19
+ this.storage = new IdTokenProviderStorage(tokenStorageKey);
20
+ }
21
+
22
+ getIdToken(): Promise<IdTokenPayload> {
23
+ return this.url
24
+ .getIdToken()
25
+ .catch(
26
+ (err) => {
27
+ console.log("No token in url, loading from storage", err);
28
+ return this.storage
29
+ .getIdToken()
30
+ .catch(
31
+ (err) => {
32
+ console.log("No token in storage, redirecting to login page", err);
33
+ return this.login.getIdToken();
34
+ }
35
+ );
36
+ }
37
+ )
38
+ .then((t) => {
39
+ this.storage.saveIdTokenToLocalStorage(t);
40
+ return t;
41
+ });
42
+ }
43
+
44
+ }
@@ -0,0 +1,39 @@
1
+ import {OAuthIdTokenProvider} from "./OAuthIdTokenProvider";
2
+ import {IdTokenPayload} from "../OAuthRestClient";
3
+ import {RedirectionProvider} from "./RedirectionProvider";
4
+ import {RestClientWithOAuth} from "../RestClientWithOAuth";
5
+ import UrlUtil from "../../util/UrlUtil";
6
+
7
+ export class IdTokenProviderLogin extends RedirectionProvider implements OAuthIdTokenProvider {
8
+
9
+ client: RestClientWithOAuth;
10
+
11
+ tokenQueryName: string;
12
+
13
+ constructor(client: RestClientWithOAuth, tokenQueryName?: string) {
14
+ super();
15
+ this.client = client;
16
+ this.tokenQueryName = tokenQueryName || 'token';
17
+ }
18
+
19
+ /**
20
+ * Attempt to get ID token from URL or storage, redirect to login page when not successful
21
+ */
22
+ redirectToLogin(): Promise<any> {
23
+ return this.client.getServerInfo().then(
24
+ (si) => {
25
+ const thisUrl = UrlUtil.deleteParamFromUrl(document.location.toString(), this.tokenQueryName);
26
+ const location = `${si.oauthServerUrl}/login?app_name=${si.targetAudience}&redirect_url=${thisUrl}`;
27
+ return this.redirectTo(location);
28
+ }
29
+ ).catch((err) => {
30
+ console.error('Redirection failed: OAuth info not fetched:', err);
31
+ return Promise.reject(err);
32
+ });
33
+ }
34
+
35
+ getIdToken(): Promise<IdTokenPayload> {
36
+ return this.redirectToLogin();
37
+ }
38
+
39
+ }
@@ -0,0 +1,32 @@
1
+ import {OAuthIdTokenProvider} from "./OAuthIdTokenProvider";
2
+ import {IdTokenPayload} from "../OAuthRestClient";
3
+ import {JsonUtil} from "../../util";
4
+
5
+ export class IdTokenProviderStorage implements OAuthIdTokenProvider {
6
+
7
+ key: string;
8
+
9
+ constructor(storageKey?: string) {
10
+ this.key = storageKey || 'id-token';
11
+ }
12
+
13
+ saveIdTokenToLocalStorage(token: IdTokenPayload | null) {
14
+ const raw = token ? JSON.stringify(token) : null;
15
+ if (raw === null) {
16
+ localStorage.removeItem(this.key);
17
+ return;
18
+ }
19
+ localStorage.setItem(this.key, raw);
20
+ }
21
+
22
+ getIdTokenFromLocalStorage(): IdTokenPayload | null | undefined {
23
+ return JsonUtil.parse(localStorage.getItem(this.key));
24
+ }
25
+
26
+ getIdToken(): Promise<IdTokenPayload> {
27
+ const token = this.getIdTokenFromLocalStorage();
28
+ if (token) return Promise.resolve(token);
29
+ return Promise.reject("No token found in storage!");
30
+ }
31
+
32
+ }
@@ -0,0 +1,30 @@
1
+ import {OAuthIdTokenProvider} from "./OAuthIdTokenProvider";
2
+ import {IdTokenPayload} from "../OAuthRestClient";
3
+ import {RestClientWithOAuth} from "../RestClientWithOAuth";
4
+ import {StringUtil} from "../../util";
5
+ import UrlUtil from "../../util/UrlUtil";
6
+
7
+ export class IdTokenProviderUrl implements OAuthIdTokenProvider {
8
+
9
+ client: RestClientWithOAuth;
10
+
11
+ tokenQueryName: string;
12
+
13
+ constructor(client: RestClientWithOAuth, tokenQueryName?: string) {
14
+ this.client = client;
15
+ this.tokenQueryName = tokenQueryName || 'token';
16
+ }
17
+
18
+ getIdTokenFromUrl(): string | null {
19
+ return UrlUtil.extractParamFromUrl(document.location.toString(), this.tokenQueryName);
20
+ }
21
+
22
+ getIdToken(): Promise<IdTokenPayload> {
23
+ const raw = this.getIdTokenFromUrl();
24
+ if (raw === null || StringUtil.isBlank(raw)) return Promise.reject("No token in URL!");
25
+ return this.client
26
+ .getTokenManager()
27
+ .then(m => m.verifyIdToken(raw));
28
+ }
29
+
30
+ }
@@ -0,0 +1,5 @@
1
+ import {IdTokenPayload} from "../OAuthRestClient";
2
+
3
+ export interface OAuthIdTokenProvider {
4
+ getIdToken(): Promise<IdTokenPayload>;
5
+ }
@@ -0,0 +1,21 @@
1
+ import {StringUtil} from "../../util";
2
+
3
+ export class RedirectionProvider {
4
+
5
+ private redirecting?: string;
6
+
7
+ redirectTo(url: string): Promise<any> {
8
+ this.redirecting = url;
9
+ document.location.href = url;
10
+ return Promise.reject(`Redirecting to ${url}`);
11
+ }
12
+
13
+ isRedirecting(): boolean {
14
+ return StringUtil.notBlank(this.redirecting);
15
+ }
16
+
17
+ redirectingTo(): string {
18
+ return StringUtil.getNonEmpty(this.redirecting);
19
+ }
20
+
21
+ }
@@ -0,0 +1,19 @@
1
+ import {StringUtil} from "./StringUtil";
2
+
3
+ export default class UrlUtil {
4
+
5
+ static deleteParamFromUrl(url: string, paramName: string): string {
6
+ const urlObj = new URL(url);
7
+ urlObj.searchParams.delete(paramName);
8
+ return StringUtil.trimTrailingSlashes(url.toString());
9
+ }
10
+
11
+ static extractParamFromUrl(url: string, name: string): string | null {
12
+ const usp = new URLSearchParams(new URL(url).search);
13
+ return usp.get(name);
14
+ }
15
+
16
+ static paramExistsInUrl(url: string, name: string): boolean {
17
+ return StringUtil.notBlank(UrlUtil.extractParamFromUrl(url, name));
18
+ }
19
+ }