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/dist/cache/CacheAsync.d.ts +2 -5
- package/dist/cache/LazyAsync.d.ts +2 -2
- package/dist/index.d.ts +12 -23
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/oauth/OAuthTokenManager.d.ts +0 -7
- package/dist/util/OAuthUtil.d.ts +6 -0
- package/package.json +1 -1
- package/src/cache/CacheAsync.ts +6 -20
- package/src/cache/LazyAsync.ts +2 -2
- package/src/oauth/OAuthTokenManager.ts +10 -43
- package/src/oauth/tokenprovider/IdTokenProviderDefault.ts +7 -5
- package/src/oauth/tokenprovider/IdTokenProviderStorage.ts +4 -3
- package/src/util/OAuthUtil.ts +24 -0
package/package.json
CHANGED
package/src/cache/CacheAsync.ts
CHANGED
@@ -1,28 +1,21 @@
|
|
1
|
-
|
1
|
+
import {LazyAsync} from "./LazyAsync";
|
2
2
|
|
3
|
-
|
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
|
-
|
10
|
+
super(supplier);
|
13
11
|
this.maxAgeMs = maxAgeMs;
|
14
12
|
}
|
15
13
|
|
16
14
|
get(): Promise<T> {
|
17
|
-
if (this.
|
18
|
-
|
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
|
}
|
package/src/cache/LazyAsync.ts
CHANGED
@@ -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
|
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
|
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 (
|
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 (!
|
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 || !
|
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 (
|
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 {
|
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(
|
39
|
-
|
40
|
-
|
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 || '
|
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
|
+
}
|