zavadil-ts-common 1.2.38 → 1.2.40

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,6 +1,7 @@
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;
@@ -8,23 +9,14 @@ export type ServerOAuthInfoPayload = {
8
9
  version: string;
9
10
  };
10
11
  export declare class RestClientWithOAuth extends RestClient {
11
- private tokenName;
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);
22
18
  /**
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
19
+ * Attempt to get ID token from the provider, this will trigger redirect to login screen in case of the default provider
28
20
  */
29
21
  initialize(): Promise<any>;
30
22
  logout(): Promise<any>;
@@ -33,23 +25,11 @@ export declare class RestClientWithOAuth extends RestClient {
33
25
  * @param url
34
26
  */
35
27
  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
28
  private getServerInfoInternal;
43
29
  getServerInfo(): Promise<ServerOAuthInfoPayload>;
44
- private getTokenManagerInternal;
30
+ protected getTokenManagerInternal(): Promise<OAuthTokenManager>;
45
31
  getTokenManager(): Promise<OAuthTokenManager>;
46
32
  login(login: string, password: string): Promise<any>;
47
33
  setIdToken(token: IdTokenPayload): Promise<any>;
48
- setIdTokenRaw(token: string): Promise<any>;
49
34
  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
35
  }
@@ -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.38",
3
+ "version": "1.2.40",
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,35 @@ export class OAuthTokenManager {
65
69
  this.accessTokens.clear();
66
70
  }
67
71
 
68
- getIdToken(): Promise<string> {
72
+ getIdTokenInternal(): Promise<IdTokenPayload> {
69
73
  if (this.idToken === undefined || !this.hasValidIdToken()) {
70
- return Promise.reject("No valid ID token!");
74
+ return this.freshIdTokenProvider.getIdToken();
71
75
  }
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;
76
+ return Promise.resolve(this.idToken);
77
+ }
78
+
79
+ getIdToken(): Promise<IdTokenPayload> {
80
+ return this.getIdTokenInternal()
81
+ .then(
82
+ (t: IdTokenPayload) => {
83
+ if (this.isTokenReadyForRefresh(t.issuedAt, t.expires)) {
84
+ return this.oAuthServer
85
+ .refreshIdToken({idToken: t.token})
86
+ .then(
87
+ (t) => {
88
+ this.setIdToken(t);
89
+ return t;
90
+ }
91
+ );
79
92
  }
80
- );
81
- }
82
- return Promise.resolve(this.idToken.token);
93
+ this.setIdToken(t);
94
+ return Promise.resolve(t);
95
+ }
96
+ );
97
+ }
98
+
99
+ getIdTokenRaw(): Promise<string> {
100
+ return this.getIdToken().then(t => t.token);
83
101
  }
84
102
 
85
103
  setIdToken(token?: IdTokenPayload) {
@@ -90,22 +108,19 @@ export class OAuthTokenManager {
90
108
  this.eventManager.triggerEvent('id-token-changed', token);
91
109
  }
92
110
 
93
- verifyIdToken(token: string): Promise<any> {
94
- return this.oAuthServer.verifyIdToken(token)
95
- .then((t) => this.setIdToken(t));
111
+ verifyIdToken(token: string): Promise<IdTokenPayload> {
112
+ return this.oAuthServer.verifyIdToken(token);
96
113
  }
97
114
 
98
115
  login(login: string, password: string): Promise<any> {
99
116
  this.reset();
100
- return this.oAuthServer.requestIdTokenFromLogin({login: login, password: password, targetAudience: this.audience})
101
- .then(
102
- (t) => {
103
- this.setIdToken(t);
104
- })
117
+ return this.oAuthServer
118
+ .requestIdTokenFromLogin({login: login, password: password, targetAudience: this.audience})
119
+ .then((t) => this.setIdToken(t));
105
120
  }
106
121
 
107
122
  private getAccessTokenInternal(privilege: string): Promise<AccessTokenPayload> {
108
- return this.getIdToken()
123
+ return this.getIdTokenRaw()
109
124
  .then(
110
125
  (idToken: string) => this.oAuthServer
111
126
  .requestAccessToken({idToken: idToken, targetAudience: this.audience, privilege: privilege})
@@ -2,7 +2,8 @@ import {OAuthTokenManager} from "./OAuthTokenManager";
2
2
  import {RestClient} from "../client";
3
3
  import {IdTokenPayload} 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;
@@ -13,20 +14,20 @@ export type ServerOAuthInfoPayload = {
13
14
 
14
15
  export class RestClientWithOAuth extends RestClient {
15
16
 
16
- private tokenName = 'token';
17
-
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,11 @@ export class RestClientWithOAuth extends RestClient {
36
37
  this.tokenManager = new LazyAsync<OAuthTokenManager>(() => this.getTokenManagerInternal());
37
38
  }
38
39
 
39
- isRedirecting(): boolean {
40
- return StringUtil.isEmpty(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 ${location}`);
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
40
  /**
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
- }
83
-
84
- /**
85
- * Attempt to get ID token from URL or storage, redirect to login page when not successful
41
+ * Attempt to get ID token from the provider, this will trigger redirect to login screen in case of the default provider
86
42
  */
87
43
  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
- );
44
+ return this.getTokenManager().then(tm => tm.getIdToken())
98
45
  }
99
46
 
100
47
  logout(): Promise<any> {
@@ -111,38 +58,6 @@ export class RestClientWithOAuth extends RestClient {
111
58
  return this.defaultPrivilege;
112
59
  }
113
60
 
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
61
  private getServerInfoInternal(): Promise<ServerOAuthInfoPayload> {
147
62
  return this.insecureClient.getJson('status/oauth/info');
148
63
  }
@@ -151,15 +66,10 @@ export class RestClientWithOAuth extends RestClient {
151
66
  return this.serverInfo.get();
152
67
  }
153
68
 
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
- );
69
+ protected getTokenManagerInternal(): Promise<OAuthTokenManager> {
70
+ return this
71
+ .getServerInfo()
72
+ .then((info) => new OAuthTokenManager(info.oauthServerUrl, info.targetAudience, this.freshIdTokenProvider));
163
73
  }
164
74
 
165
75
  getTokenManager(): Promise<OAuthTokenManager> {
@@ -175,10 +85,6 @@ export class RestClientWithOAuth extends RestClient {
175
85
  .then((m) => m.setIdToken(token));
176
86
  }
177
87
 
178
- setIdTokenRaw(token: string): Promise<any> {
179
- return this.getTokenManager().then(m => m.verifyIdToken(token))
180
- }
181
-
182
88
  getHeaders(endpoint: string): Promise<Headers> {
183
89
  return this.getTokenManager()
184
90
  .then(tm => tm.getAccessToken(this.getPrivilege(endpoint)))
@@ -193,14 +99,4 @@ export class RestClientWithOAuth extends RestClient {
193
99
  );
194
100
  }
195
101
 
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
102
  }
@@ -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
+ }