zavadil-ts-common 1.2.40 → 1.2.42
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/index.d.ts +9 -9
- 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 +6 -7
- package/dist/oauth/RestClientWithOAuth.d.ts +3 -2
- package/dist/util/OAuthUtil.d.ts +6 -0
- package/package.json +1 -1
- package/src/oauth/OAuthTokenManager.ts +16 -43
- package/src/oauth/RestClientWithOAuth.ts +8 -4
- package/src/oauth/tokenprovider/IdTokenProviderDefault.ts +7 -5
- package/src/oauth/tokenprovider/IdTokenProviderStorage.ts +4 -3
- package/src/util/OAuthUtil.ts +24 -0
@@ -8,15 +8,16 @@ export type ServerOAuthInfoPayload = {
|
|
8
8
|
oauthServerUrl: string;
|
9
9
|
version: string;
|
10
10
|
};
|
11
|
-
export declare class RestClientWithOAuth extends RestClient {
|
11
|
+
export declare class RestClientWithOAuth extends RestClient implements OAuthIdTokenProvider {
|
12
12
|
private insecureClient;
|
13
13
|
private freshIdTokenProvider;
|
14
14
|
private tokenManager;
|
15
15
|
private serverInfo;
|
16
16
|
private defaultPrivilege;
|
17
17
|
constructor(url: string, freshIdTokenProvider?: OAuthIdTokenProvider, defaultPrivilege?: string);
|
18
|
+
getIdToken(): Promise<IdTokenPayload>;
|
18
19
|
/**
|
19
|
-
* Attempt to get ID token from
|
20
|
+
* Attempt to get ID token from token manager
|
20
21
|
*/
|
21
22
|
initialize(): Promise<any>;
|
22
23
|
logout(): Promise<any>;
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { TokenResponsePayloadBase } from "../oauth";
|
2
|
+
export declare class OAuthUtil {
|
3
|
+
static isValidToken(token?: TokenResponsePayloadBase | null): boolean;
|
4
|
+
static isTokenExpired(token?: TokenResponsePayloadBase | null): boolean;
|
5
|
+
static isTokenReadyForRefresh(token?: TokenResponsePayloadBase | null): boolean;
|
6
|
+
}
|
package/package.json
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,48 +24,22 @@ 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
|
|
40
|
+
/**
|
41
|
+
* Get stored id token or ask the provider, this will trigger redirect to login screen in case of the default provider
|
42
|
+
*/
|
72
43
|
getIdTokenInternal(): Promise<IdTokenPayload> {
|
73
44
|
if (this.idToken === undefined || !this.hasValidIdToken()) {
|
74
45
|
return this.freshIdTokenProvider.getIdToken();
|
@@ -76,11 +47,17 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
|
|
76
47
|
return Promise.resolve(this.idToken);
|
77
48
|
}
|
78
49
|
|
50
|
+
/**
|
51
|
+
* Get id token, refresh it if needed
|
52
|
+
*/
|
79
53
|
getIdToken(): Promise<IdTokenPayload> {
|
80
54
|
return this.getIdTokenInternal()
|
81
55
|
.then(
|
82
56
|
(t: IdTokenPayload) => {
|
83
|
-
if (
|
57
|
+
if (!OAuthUtil.isValidToken(t)) {
|
58
|
+
return Promise.reject('Received invalid ID token!');
|
59
|
+
}
|
60
|
+
if (OAuthUtil.isTokenReadyForRefresh(t)) {
|
84
61
|
return this.oAuthServer
|
85
62
|
.refreshIdToken({idToken: t.token})
|
86
63
|
.then(
|
@@ -101,11 +78,7 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
|
|
101
78
|
}
|
102
79
|
|
103
80
|
setIdToken(token?: IdTokenPayload) {
|
104
|
-
if (!this.isValidIdToken(token)) {
|
105
|
-
throw new Error("Received ID token is not valid!");
|
106
|
-
}
|
107
81
|
this.idToken = token;
|
108
|
-
this.eventManager.triggerEvent('id-token-changed', token);
|
109
82
|
}
|
110
83
|
|
111
84
|
verifyIdToken(token: string): Promise<IdTokenPayload> {
|
@@ -125,7 +98,7 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
|
|
125
98
|
(idToken: string) => this.oAuthServer
|
126
99
|
.requestAccessToken({idToken: idToken, targetAudience: this.audience, privilege: privilege})
|
127
100
|
.then((act: AccessTokenPayload) => {
|
128
|
-
if (!
|
101
|
+
if (!OAuthUtil.isValidToken(act)) {
|
129
102
|
return Promise.reject("Received access token is not valid!");
|
130
103
|
}
|
131
104
|
this.accessTokens.set(privilege, act);
|
@@ -136,9 +109,9 @@ export class OAuthTokenManager implements OAuthIdTokenProvider {
|
|
136
109
|
|
137
110
|
getAccessToken(privilege: string): Promise<string> {
|
138
111
|
const existing = this.accessTokens.get(privilege);
|
139
|
-
if (existing === undefined || !
|
112
|
+
if (existing === undefined || !OAuthUtil.isValidToken(existing)) return this.getAccessTokenInternal(privilege).then((t) => t.token);
|
140
113
|
// preload access token if it is going to expire soon
|
141
|
-
if (
|
114
|
+
if (OAuthUtil.isTokenReadyForRefresh(existing)) this.getAccessTokenInternal(privilege);
|
142
115
|
return Promise.resolve(existing.token);
|
143
116
|
}
|
144
117
|
|
@@ -1,6 +1,6 @@
|
|
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
5
|
import {OAuthIdTokenProvider} from "./tokenprovider/OAuthIdTokenProvider";
|
6
6
|
import {IdTokenProviderDefault} from "./tokenprovider/IdTokenProviderDefault";
|
@@ -12,7 +12,7 @@ export type ServerOAuthInfoPayload = {
|
|
12
12
|
version: string;
|
13
13
|
}
|
14
14
|
|
15
|
-
export class RestClientWithOAuth extends RestClient {
|
15
|
+
export class RestClientWithOAuth extends RestClient implements OAuthIdTokenProvider {
|
16
16
|
|
17
17
|
private insecureClient: RestClient;
|
18
18
|
|
@@ -37,11 +37,15 @@ export class RestClientWithOAuth extends RestClient {
|
|
37
37
|
this.tokenManager = new LazyAsync<OAuthTokenManager>(() => this.getTokenManagerInternal());
|
38
38
|
}
|
39
39
|
|
40
|
+
getIdToken(): Promise<IdTokenPayload> {
|
41
|
+
return this.getTokenManager().then(t => t.getIdToken());
|
42
|
+
}
|
43
|
+
|
40
44
|
/**
|
41
|
-
* Attempt to get ID token from
|
45
|
+
* Attempt to get ID token from token manager
|
42
46
|
*/
|
43
47
|
initialize(): Promise<any> {
|
44
|
-
return this.
|
48
|
+
return this.getIdToken();
|
45
49
|
}
|
46
50
|
|
47
51
|
logout(): Promise<any> {
|
@@ -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
|
+
}
|