zavadil-ts-common 1.2.41 → 1.2.43

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zavadil-ts-common",
3
- "version": "1.2.41",
3
+ "version": "1.2.43",
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,28 +1,21 @@
1
- export class CacheAsync<T> {
1
+ import {LazyAsync} from "./LazyAsync";
2
2
 
3
- private cache?: T;
4
-
5
- private supplier: () => Promise<T>;
3
+ export class CacheAsync<T> extends LazyAsync<T> {
6
4
 
7
5
  private maxAgeMs?: number;
8
6
 
9
7
  private expires?: Date;
10
8
 
11
9
  constructor(supplier: () => Promise<T>, maxAgeMs?: number) {
12
- this.supplier = supplier;
10
+ super(supplier);
13
11
  this.maxAgeMs = maxAgeMs;
14
12
  }
15
13
 
16
14
  get(): Promise<T> {
17
- if (this.cache === undefined || (this.expires && this.expires > new Date())) {
18
- return this.supplier()
19
- .then((v: T) => {
20
- this.set(v);
21
- return v;
22
- });
23
- } else {
24
- return Promise.resolve(this.cache);
15
+ if (this.expires && this.expires > new Date()) {
16
+ this.reset();
25
17
  }
18
+ return super.get();
26
19
  }
27
20
 
28
21
  set(v: T, expires?: Date) {
@@ -33,11 +26,4 @@ export class CacheAsync<T> {
33
26
  }
34
27
  }
35
28
 
36
- hasCache() {
37
- return (this.cache !== undefined);
38
- }
39
-
40
- getCache(): T | undefined {
41
- return this.cache;
42
- }
43
29
  }
@@ -1,8 +1,8 @@
1
1
  export class LazyAsync<T> {
2
2
 
3
- private cache?: T;
3
+ protected cache?: T;
4
4
 
5
- private supplier: () => Promise<T>;
5
+ protected supplier: () => Promise<T>;
6
6
 
7
7
  private promise?: Promise<T>;
8
8
 
@@ -1,15 +1,12 @@
1
1
  import {AccessTokenPayload, IdTokenPayload, OAuthRestClient} from "./OAuthRestClient";
2
- import {EventManager} from "../component";
3
- import {StringUtil} from "../util";
4
2
  import {OAuthIdTokenProvider} from "./tokenprovider/OAuthIdTokenProvider";
3
+ import {OAuthUtil} from "../util/OAuthUtil";
5
4
 
6
5
  /**
7
6
  * Manages refresh of id and access tokens.
8
7
  */
9
8
  export class OAuthTokenManager implements OAuthIdTokenProvider {
10
9
 
11
- private eventManager: EventManager = new EventManager();
12
-
13
10
  oAuthServer: OAuthRestClient;
14
11
 
15
12
  audience: string;
@@ -27,45 +24,16 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
27
24
  this.accessTokens = new Map<string, AccessTokenPayload>();
28
25
  }
29
26
 
30
- addIdTokenChangedHandler(handler: (t: IdTokenPayload) => any) {
31
- this.eventManager.addEventListener('id-token-changed', handler);
32
- }
33
-
34
- removeIdTokenChangedHandler(handler: (t: IdTokenPayload) => any) {
35
- this.eventManager.removeEventListener('id-token-changed', handler);
36
- }
37
-
38
- isTokenExpired(expires?: Date | null): boolean {
39
- if (expires === undefined || expires === null) return false;
40
- return (expires < new Date());
41
- }
42
-
43
- isTokenReadyForRefresh(issuedAt: Date, expires?: Date | null): boolean {
44
- if (expires === undefined || expires === null) return false;
45
- const middle = new Date((expires.getTime() + issuedAt.getTime()) / 2);
46
- const now = new Date();
47
- return (middle < now);
48
- }
49
-
50
- isValidIdToken(idToken?: IdTokenPayload): boolean {
51
- return idToken !== undefined && StringUtil.notEmpty(idToken.token) && !this.isTokenExpired(idToken.expires);
52
- }
53
-
54
27
  hasValidIdToken(): boolean {
55
- return this.isValidIdToken(this.idToken);
56
- }
57
-
58
- isValidAccessToken(accessToken?: AccessTokenPayload): boolean {
59
- return accessToken !== undefined && StringUtil.notEmpty(accessToken.token) && !this.isTokenExpired(accessToken.expires);
28
+ return OAuthUtil.isValidToken(this.idToken);
60
29
  }
61
30
 
62
31
  hasValidAccessToken(privilege: string): boolean {
63
- return this.isValidAccessToken(this.accessTokens.get(privilege));
32
+ return OAuthUtil.isValidToken(this.accessTokens.get(privilege));
64
33
  }
65
34
 
66
35
  reset() {
67
36
  this.idToken = undefined;
68
- this.eventManager.triggerEvent('id-token-changed', undefined);
69
37
  this.accessTokens.clear();
70
38
  }
71
39
 
@@ -86,7 +54,10 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
86
54
  return this.getIdTokenInternal()
87
55
  .then(
88
56
  (t: IdTokenPayload) => {
89
- if (this.isTokenReadyForRefresh(t.issuedAt, t.expires)) {
57
+ if (!OAuthUtil.isValidToken(t)) {
58
+ return Promise.reject('Received invalid ID token!');
59
+ }
60
+ if (OAuthUtil.isTokenReadyForRefresh(t)) {
90
61
  return this.oAuthServer
91
62
  .refreshIdToken({idToken: t.token})
92
63
  .then(
@@ -107,11 +78,7 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
107
78
  }
108
79
 
109
80
  setIdToken(token?: IdTokenPayload) {
110
- if (!this.isValidIdToken(token)) {
111
- throw new Error("Received ID token is not valid!");
112
- }
113
81
  this.idToken = token;
114
- this.eventManager.triggerEvent('id-token-changed', token);
115
82
  }
116
83
 
117
84
  verifyIdToken(token: string): Promise<IdTokenPayload> {
@@ -131,7 +98,7 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
131
98
  (idToken: string) => this.oAuthServer
132
99
  .requestAccessToken({idToken: idToken, targetAudience: this.audience, privilege: privilege})
133
100
  .then((act: AccessTokenPayload) => {
134
- if (!this.isValidAccessToken(act)) {
101
+ if (!OAuthUtil.isValidToken(act)) {
135
102
  return Promise.reject("Received access token is not valid!");
136
103
  }
137
104
  this.accessTokens.set(privilege, act);
@@ -142,9 +109,9 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
142
109
 
143
110
  getAccessToken(privilege: string): Promise<string> {
144
111
  const existing = this.accessTokens.get(privilege);
145
- if (existing === undefined || !this.isValidAccessToken(existing)) return this.getAccessTokenInternal(privilege).then((t) => t.token);
112
+ if (existing === undefined || !OAuthUtil.isValidToken(existing)) return this.getAccessTokenInternal(privilege).then((t) => t.token);
146
113
  // preload access token if it is going to expire soon
147
- if (this.isTokenReadyForRefresh(existing.issuedAt, existing.expires)) this.getAccessTokenInternal(privilege);
114
+ if (OAuthUtil.isTokenReadyForRefresh(existing)) this.getAccessTokenInternal(privilege);
148
115
  return Promise.resolve(existing.token);
149
116
  }
150
117
 
@@ -2,7 +2,7 @@ import {OAuthIdTokenProvider} from "./OAuthIdTokenProvider";
2
2
  import {IdTokenPayload} from "../OAuthRestClient";
3
3
  import {IdTokenProviderLogin} from "./IdTokenProviderLogin";
4
4
  import {RestClientWithOAuth} from "../RestClientWithOAuth";
5
- import { IdTokenProviderUrl } from "./IdTokenProviderUrl";
5
+ import {IdTokenProviderUrl} from "./IdTokenProviderUrl";
6
6
  import {IdTokenProviderStorage} from "./IdTokenProviderStorage";
7
7
 
8
8
  export class IdTokenProviderDefault implements OAuthIdTokenProvider {
@@ -35,10 +35,12 @@ export class IdTokenProviderDefault implements OAuthIdTokenProvider {
35
35
  );
36
36
  }
37
37
  )
38
- .then((t) => {
39
- this.storage.saveIdTokenToLocalStorage(t);
40
- return t;
41
- });
38
+ .then(
39
+ (t) => {
40
+ this.storage.saveIdTokenToLocalStorage(t);
41
+ return t;
42
+ }
43
+ );
42
44
  }
43
45
 
44
46
  }
@@ -1,13 +1,14 @@
1
1
  import {OAuthIdTokenProvider} from "./OAuthIdTokenProvider";
2
2
  import {IdTokenPayload} from "../OAuthRestClient";
3
3
  import {JsonUtil} from "../../util";
4
+ import {OAuthUtil} from "../../util/OAuthUtil";
4
5
 
5
6
  export class IdTokenProviderStorage implements OAuthIdTokenProvider {
6
7
 
7
8
  key: string;
8
9
 
9
10
  constructor(storageKey?: string) {
10
- this.key = storageKey || 'id-token';
11
+ this.key = storageKey || '';
11
12
  }
12
13
 
13
14
  saveIdTokenToLocalStorage(token: IdTokenPayload | null) {
@@ -25,8 +26,8 @@ export class IdTokenProviderStorage implements OAuthIdTokenProvider {
25
26
 
26
27
  getIdToken(): Promise<IdTokenPayload> {
27
28
  const token = this.getIdTokenFromLocalStorage();
28
- if (token) return Promise.resolve(token);
29
- return Promise.reject("No token found in storage!");
29
+ if (token && OAuthUtil.isValidToken(token)) return Promise.resolve(token);
30
+ return Promise.reject("No valid token found in storage!");
30
31
  }
31
32
 
32
33
  }
@@ -0,0 +1,24 @@
1
+ import {TokenResponsePayloadBase} from "../oauth";
2
+ import {StringUtil} from "./StringUtil";
3
+
4
+ export class OAuthUtil {
5
+
6
+ static isValidToken(token?: TokenResponsePayloadBase | null): boolean {
7
+ return token !== undefined && token !== null && StringUtil.notEmpty(token.token) && !OAuthUtil.isTokenExpired(token);
8
+ }
9
+
10
+ static isTokenExpired(token?: TokenResponsePayloadBase | null): boolean {
11
+ if (token === undefined || token === null) return false;
12
+ if (token.expires === undefined || token.expires === null) return false;
13
+ return (token.expires < new Date());
14
+ }
15
+
16
+ static isTokenReadyForRefresh(token?: TokenResponsePayloadBase | null): boolean {
17
+ if (token === undefined || token === null) return false;
18
+ if (OAuthUtil.isTokenExpired(token)) return false;
19
+ if (token.expires === undefined || token.expires === null) return false;
20
+ const middle = new Date((token.expires.getTime() + token.issuedAt.getTime()) / 2);
21
+ const now = new Date();
22
+ return (middle < now);
23
+ }
24
+ }