@meshagent/meshagent-ts-auth 0.35.6
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/CHANGELOG.md +2 -0
- package/LICENSE +201 -0
- package/README.md +271 -0
- package/dist/browser/access-token-provider.d.ts +9 -0
- package/dist/browser/browser-global.d.ts +7 -0
- package/dist/browser/ensure-login.d.ts +6 -0
- package/dist/browser/index.d.ts +7 -0
- package/dist/browser/ma-auth.global.js +26382 -0
- package/dist/browser/mauth-response.d.ts +15 -0
- package/dist/browser/meshagent-auth.d.ts +40 -0
- package/dist/browser/oauth-session-manager.d.ts +22 -0
- package/dist/browser/pkce-generator.d.ts +27 -0
- package/dist/browser/storage.d.ts +6 -0
- package/dist/cjs/access-token-provider.d.ts +9 -0
- package/dist/cjs/access-token-provider.js +19 -0
- package/dist/cjs/browser-global.d.ts +7 -0
- package/dist/cjs/browser-global.js +2 -0
- package/dist/cjs/ensure-login.d.ts +6 -0
- package/dist/cjs/ensure-login.js +118 -0
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.js +23 -0
- package/dist/cjs/mauth-response.d.ts +15 -0
- package/dist/cjs/mauth-response.js +94 -0
- package/dist/cjs/meshagent-auth.d.ts +40 -0
- package/dist/cjs/meshagent-auth.js +177 -0
- package/dist/cjs/oauth-session-manager.d.ts +22 -0
- package/dist/cjs/oauth-session-manager.js +116 -0
- package/dist/cjs/pkce-generator.d.ts +27 -0
- package/dist/cjs/pkce-generator.js +94 -0
- package/dist/cjs/storage.d.ts +6 -0
- package/dist/cjs/storage.js +29 -0
- package/dist/esm/access-token-provider.d.ts +9 -0
- package/dist/esm/access-token-provider.js +15 -0
- package/dist/esm/browser-global.d.ts +7 -0
- package/dist/esm/browser-global.js +1 -0
- package/dist/esm/ensure-login.d.ts +6 -0
- package/dist/esm/ensure-login.js +115 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/mauth-response.d.ts +15 -0
- package/dist/esm/mauth-response.js +88 -0
- package/dist/esm/meshagent-auth.d.ts +40 -0
- package/dist/esm/meshagent-auth.js +173 -0
- package/dist/esm/oauth-session-manager.d.ts +22 -0
- package/dist/esm/oauth-session-manager.js +112 -0
- package/dist/esm/pkce-generator.d.ts +27 -0
- package/dist/esm/pkce-generator.js +89 -0
- package/dist/esm/storage.d.ts +6 -0
- package/dist/esm/storage.js +26 -0
- package/package.json +50 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { getDefaultStorage } from "./storage";
|
|
2
|
+
const ACCESS_TOKEN_KEY = "ma:access_token";
|
|
3
|
+
const REFRESH_TOKEN_KEY = "ma:refresh_token";
|
|
4
|
+
const EXPIRATION_KEY = "ma:expiration";
|
|
5
|
+
function parseExpiration(value) {
|
|
6
|
+
if (!value) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const parsed = new Date(value);
|
|
10
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
11
|
+
}
|
|
12
|
+
function buildExpiration(expiresIn) {
|
|
13
|
+
if (expiresIn == null || !Number.isFinite(expiresIn)) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return new Date(Date.now() + expiresIn * 1000);
|
|
17
|
+
}
|
|
18
|
+
function sameDate(left, right) {
|
|
19
|
+
if (left === right) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
if (!left || !right) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return left.getTime() === right.getTime();
|
|
26
|
+
}
|
|
27
|
+
export class MeshagentAuth {
|
|
28
|
+
constructor(storage = getDefaultStorage()) {
|
|
29
|
+
Object.defineProperty(this, "storage", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "listeners", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: new Set()
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(this, "snapshot", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true,
|
|
45
|
+
value: void 0
|
|
46
|
+
});
|
|
47
|
+
this.storage = storage;
|
|
48
|
+
this.snapshot = {
|
|
49
|
+
accessToken: this.storage.getItem(ACCESS_TOKEN_KEY),
|
|
50
|
+
refreshToken: this.storage.getItem(REFRESH_TOKEN_KEY),
|
|
51
|
+
expiration: parseExpiration(this.storage.getItem(EXPIRATION_KEY)),
|
|
52
|
+
user: null,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
subscribe(listener) {
|
|
56
|
+
this.listeners.add(listener);
|
|
57
|
+
return () => {
|
|
58
|
+
this.listeners.delete(listener);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
getSnapshot() {
|
|
62
|
+
return this.snapshot;
|
|
63
|
+
}
|
|
64
|
+
setSession(session) {
|
|
65
|
+
this.writeValue(ACCESS_TOKEN_KEY, session.accessToken);
|
|
66
|
+
this.writeValue(REFRESH_TOKEN_KEY, session.refreshToken);
|
|
67
|
+
const expiration = buildExpiration(session.expiresIn);
|
|
68
|
+
if (expiration) {
|
|
69
|
+
this.storage.setItem(EXPIRATION_KEY, expiration.toISOString());
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
this.storage.removeItem(EXPIRATION_KEY);
|
|
73
|
+
}
|
|
74
|
+
this.publish({
|
|
75
|
+
...this.snapshot,
|
|
76
|
+
accessToken: session.accessToken,
|
|
77
|
+
refreshToken: session.refreshToken,
|
|
78
|
+
expiration,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
setUser(user) {
|
|
82
|
+
this.publish({
|
|
83
|
+
...this.snapshot,
|
|
84
|
+
user,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
getUser() {
|
|
88
|
+
return this.snapshot.user;
|
|
89
|
+
}
|
|
90
|
+
signOut() {
|
|
91
|
+
this.writeValue(ACCESS_TOKEN_KEY, null);
|
|
92
|
+
this.writeValue(REFRESH_TOKEN_KEY, null);
|
|
93
|
+
this.storage.removeItem(EXPIRATION_KEY);
|
|
94
|
+
this.publish({
|
|
95
|
+
accessToken: null,
|
|
96
|
+
refreshToken: null,
|
|
97
|
+
expiration: null,
|
|
98
|
+
user: null,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
isLoggedIn() {
|
|
102
|
+
return this.snapshot.accessToken !== null;
|
|
103
|
+
}
|
|
104
|
+
get expiration() {
|
|
105
|
+
return this.snapshot.expiration;
|
|
106
|
+
}
|
|
107
|
+
isExpired() {
|
|
108
|
+
const expiration = this.expiration;
|
|
109
|
+
return expiration ? expiration.getTime() <= Date.now() : false;
|
|
110
|
+
}
|
|
111
|
+
getAccessToken() {
|
|
112
|
+
return this.snapshot.accessToken;
|
|
113
|
+
}
|
|
114
|
+
getRefreshToken() {
|
|
115
|
+
return this.snapshot.refreshToken;
|
|
116
|
+
}
|
|
117
|
+
setAccessToken(token) {
|
|
118
|
+
this.writeValue(ACCESS_TOKEN_KEY, token);
|
|
119
|
+
this.publish({
|
|
120
|
+
...this.snapshot,
|
|
121
|
+
accessToken: token,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
setRefreshToken(refreshToken) {
|
|
125
|
+
this.writeValue(REFRESH_TOKEN_KEY, refreshToken);
|
|
126
|
+
this.publish({
|
|
127
|
+
...this.snapshot,
|
|
128
|
+
refreshToken,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
setExpiresIn(expiresIn) {
|
|
132
|
+
const expiration = buildExpiration(expiresIn);
|
|
133
|
+
if (expiration) {
|
|
134
|
+
this.storage.setItem(EXPIRATION_KEY, expiration.toISOString());
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this.storage.removeItem(EXPIRATION_KEY);
|
|
138
|
+
}
|
|
139
|
+
this.publish({
|
|
140
|
+
...this.snapshot,
|
|
141
|
+
expiration,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
writeValue(key, value) {
|
|
145
|
+
if (!value) {
|
|
146
|
+
this.storage.removeItem(key);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.storage.setItem(key, value);
|
|
150
|
+
}
|
|
151
|
+
publish(nextSnapshot) {
|
|
152
|
+
if (this.isEqual(nextSnapshot)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.snapshot = nextSnapshot;
|
|
156
|
+
for (const listener of this.listeners) {
|
|
157
|
+
listener();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
isEqual(nextSnapshot) {
|
|
161
|
+
return this.snapshot.accessToken === nextSnapshot.accessToken
|
|
162
|
+
&& this.snapshot.refreshToken === nextSnapshot.refreshToken
|
|
163
|
+
&& sameDate(this.snapshot.expiration, nextSnapshot.expiration)
|
|
164
|
+
&& this.snapshot.user === nextSnapshot.user;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
Object.defineProperty(MeshagentAuth, "current", {
|
|
168
|
+
enumerable: true,
|
|
169
|
+
configurable: true,
|
|
170
|
+
writable: true,
|
|
171
|
+
value: new MeshagentAuth()
|
|
172
|
+
});
|
|
173
|
+
export const meshagentAuth = MeshagentAuth.current;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MeshagentAuth } from "./meshagent-auth";
|
|
2
|
+
export interface OAuthSessionManagerOptions {
|
|
3
|
+
serverUrl: string | URL;
|
|
4
|
+
clientId: string;
|
|
5
|
+
clientSecret?: string;
|
|
6
|
+
refreshSkew?: number;
|
|
7
|
+
minValidFor?: number;
|
|
8
|
+
auth?: MeshagentAuth;
|
|
9
|
+
}
|
|
10
|
+
export declare class OAuthSessionManager {
|
|
11
|
+
readonly serverUrl: URL;
|
|
12
|
+
readonly clientId: string;
|
|
13
|
+
readonly clientSecret?: string;
|
|
14
|
+
readonly refreshSkew: number;
|
|
15
|
+
readonly minValidFor: number;
|
|
16
|
+
private readonly auth;
|
|
17
|
+
constructor({ serverUrl, clientId, clientSecret, refreshSkew, minValidFor, auth, }: OAuthSessionManagerOptions);
|
|
18
|
+
get isLoggedIn(): boolean;
|
|
19
|
+
getValidAccessTokenOrThrow(): Promise<string>;
|
|
20
|
+
isAccessTokenValidEnough(): boolean;
|
|
21
|
+
refreshOrThrow(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { meshagentAuth } from "./meshagent-auth";
|
|
2
|
+
function toUrl(value) {
|
|
3
|
+
return value instanceof URL ? value : new URL(value);
|
|
4
|
+
}
|
|
5
|
+
export class OAuthSessionManager {
|
|
6
|
+
constructor({ serverUrl, clientId, clientSecret, refreshSkew = 2 * 60 * 1000, minValidFor = 8 * 60 * 60 * 1000, auth = meshagentAuth, }) {
|
|
7
|
+
Object.defineProperty(this, "serverUrl", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: void 0
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(this, "clientId", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: void 0
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "clientSecret", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: void 0
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(this, "refreshSkew", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: void 0
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(this, "minValidFor", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
writable: true,
|
|
35
|
+
value: void 0
|
|
36
|
+
});
|
|
37
|
+
Object.defineProperty(this, "auth", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
writable: true,
|
|
41
|
+
value: void 0
|
|
42
|
+
});
|
|
43
|
+
this.serverUrl = toUrl(serverUrl);
|
|
44
|
+
this.clientId = clientId;
|
|
45
|
+
this.clientSecret = clientSecret;
|
|
46
|
+
this.refreshSkew = refreshSkew;
|
|
47
|
+
this.minValidFor = minValidFor;
|
|
48
|
+
this.auth = auth;
|
|
49
|
+
}
|
|
50
|
+
get isLoggedIn() {
|
|
51
|
+
return this.auth.isLoggedIn();
|
|
52
|
+
}
|
|
53
|
+
async getValidAccessTokenOrThrow() {
|
|
54
|
+
const token = this.auth.getAccessToken();
|
|
55
|
+
if (!token) {
|
|
56
|
+
throw new Error("Not logged in");
|
|
57
|
+
}
|
|
58
|
+
if (this.isAccessTokenValidEnough()) {
|
|
59
|
+
return token;
|
|
60
|
+
}
|
|
61
|
+
await this.refreshOrThrow();
|
|
62
|
+
const refreshed = this.auth.getAccessToken();
|
|
63
|
+
if (!refreshed) {
|
|
64
|
+
throw new Error("Refresh succeeded but access token is missing");
|
|
65
|
+
}
|
|
66
|
+
return refreshed;
|
|
67
|
+
}
|
|
68
|
+
isAccessTokenValidEnough() {
|
|
69
|
+
const expiration = this.auth.expiration;
|
|
70
|
+
if (!expiration) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const threshold = Date.now() + this.minValidFor + this.refreshSkew;
|
|
74
|
+
return expiration.getTime() > threshold;
|
|
75
|
+
}
|
|
76
|
+
async refreshOrThrow() {
|
|
77
|
+
const refreshToken = this.auth.getRefreshToken();
|
|
78
|
+
if (!refreshToken) {
|
|
79
|
+
throw new Error("No refresh token available");
|
|
80
|
+
}
|
|
81
|
+
const response = await fetch(new URL("/oauth/token", this.serverUrl), {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: {
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
"Accept": "application/json",
|
|
86
|
+
},
|
|
87
|
+
body: JSON.stringify({
|
|
88
|
+
grant_type: "refresh_token",
|
|
89
|
+
refresh_token: refreshToken,
|
|
90
|
+
client_id: this.clientId,
|
|
91
|
+
...(this.clientSecret ? { client_secret: this.clientSecret } : {}),
|
|
92
|
+
}),
|
|
93
|
+
});
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
throw new Error(`Failed to refresh token: ${response.status} ${await response.text()}`);
|
|
96
|
+
}
|
|
97
|
+
const data = await response.json();
|
|
98
|
+
const accessToken = data["access_token"];
|
|
99
|
+
const nextRefreshToken = data["refresh_token"];
|
|
100
|
+
const expiresIn = data["expires_in"];
|
|
101
|
+
if (typeof accessToken !== "string" || accessToken.length === 0) {
|
|
102
|
+
throw new Error("Refresh response missing access_token");
|
|
103
|
+
}
|
|
104
|
+
this.auth.setSession({
|
|
105
|
+
accessToken,
|
|
106
|
+
refreshToken: typeof nextRefreshToken === "string" && nextRefreshToken.length > 0
|
|
107
|
+
? nextRefreshToken
|
|
108
|
+
: refreshToken,
|
|
109
|
+
expiresIn: typeof expiresIn === "number" ? expiresIn : null,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { StorageLike } from "./storage";
|
|
2
|
+
export interface PkceCache {
|
|
3
|
+
saveVerifier(verifier: string): Promise<void>;
|
|
4
|
+
readVerifier(): Promise<string | null>;
|
|
5
|
+
clearVerifier(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare class LocalStoragePkceCache implements PkceCache {
|
|
8
|
+
private readonly storage;
|
|
9
|
+
constructor(storage?: StorageLike);
|
|
10
|
+
saveVerifier(verifier: string): Promise<void>;
|
|
11
|
+
readVerifier(): Promise<string | null>;
|
|
12
|
+
clearVerifier(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export interface PkcePair {
|
|
15
|
+
codeVerifier: string;
|
|
16
|
+
codeChallenge: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class PkceGenerator {
|
|
19
|
+
static readonly minVerifierLength = 43;
|
|
20
|
+
static readonly maxVerifierLength = 128;
|
|
21
|
+
private readonly cryptoApi;
|
|
22
|
+
constructor(cryptoApi?: Crypto);
|
|
23
|
+
generate(verifierLength?: number): Promise<PkcePair>;
|
|
24
|
+
private validateLength;
|
|
25
|
+
private generateCodeVerifier;
|
|
26
|
+
private createCodeChallenge;
|
|
27
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { getDefaultStorage } from "./storage";
|
|
2
|
+
const PKCE_VERIFIER_KEY = "cv";
|
|
3
|
+
export class LocalStoragePkceCache {
|
|
4
|
+
constructor(storage = getDefaultStorage()) {
|
|
5
|
+
Object.defineProperty(this, "storage", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: void 0
|
|
10
|
+
});
|
|
11
|
+
this.storage = storage;
|
|
12
|
+
}
|
|
13
|
+
async saveVerifier(verifier) {
|
|
14
|
+
this.storage.setItem(PKCE_VERIFIER_KEY, verifier);
|
|
15
|
+
}
|
|
16
|
+
async readVerifier() {
|
|
17
|
+
return this.storage.getItem(PKCE_VERIFIER_KEY);
|
|
18
|
+
}
|
|
19
|
+
async clearVerifier() {
|
|
20
|
+
this.storage.removeItem(PKCE_VERIFIER_KEY);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function assertCryptoAvailable() {
|
|
24
|
+
if (!globalThis.crypto || typeof globalThis.crypto.getRandomValues !== "function" || !globalThis.crypto.subtle) {
|
|
25
|
+
throw new Error("Web Crypto is required for PKCE generation");
|
|
26
|
+
}
|
|
27
|
+
return globalThis.crypto;
|
|
28
|
+
}
|
|
29
|
+
function encodeBase64Url(bytes) {
|
|
30
|
+
let binary = "";
|
|
31
|
+
for (const byte of bytes) {
|
|
32
|
+
binary += String.fromCharCode(byte);
|
|
33
|
+
}
|
|
34
|
+
const base64 = globalThis.btoa(binary);
|
|
35
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
36
|
+
}
|
|
37
|
+
export class PkceGenerator {
|
|
38
|
+
constructor(cryptoApi = assertCryptoAvailable()) {
|
|
39
|
+
Object.defineProperty(this, "cryptoApi", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true,
|
|
43
|
+
value: void 0
|
|
44
|
+
});
|
|
45
|
+
this.cryptoApi = cryptoApi;
|
|
46
|
+
}
|
|
47
|
+
async generate(verifierLength = 64) {
|
|
48
|
+
this.validateLength(verifierLength);
|
|
49
|
+
const verifier = this.generateCodeVerifier(verifierLength);
|
|
50
|
+
const challenge = await this.createCodeChallenge(verifier);
|
|
51
|
+
return {
|
|
52
|
+
codeVerifier: verifier,
|
|
53
|
+
codeChallenge: challenge,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
validateLength(length) {
|
|
57
|
+
if (length < PkceGenerator.minVerifierLength || length > PkceGenerator.maxVerifierLength) {
|
|
58
|
+
throw new Error(`verifierLength must be between ${PkceGenerator.minVerifierLength} and ${PkceGenerator.maxVerifierLength}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
generateCodeVerifier(targetLength) {
|
|
62
|
+
let bytesNeeded = Math.ceil((targetLength * 3) / 4);
|
|
63
|
+
while (true) {
|
|
64
|
+
const bytes = new Uint8Array(bytesNeeded);
|
|
65
|
+
this.cryptoApi.getRandomValues(bytes);
|
|
66
|
+
const candidate = encodeBase64Url(bytes);
|
|
67
|
+
if (candidate.length >= targetLength) {
|
|
68
|
+
return candidate.slice(0, targetLength);
|
|
69
|
+
}
|
|
70
|
+
bytesNeeded = Math.ceil(bytesNeeded * 1.25);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async createCodeChallenge(codeVerifier) {
|
|
74
|
+
const digest = await this.cryptoApi.subtle.digest("SHA-256", new TextEncoder().encode(codeVerifier));
|
|
75
|
+
return encodeBase64Url(new Uint8Array(digest));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
Object.defineProperty(PkceGenerator, "minVerifierLength", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
writable: true,
|
|
82
|
+
value: 43
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(PkceGenerator, "maxVerifierLength", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
configurable: true,
|
|
87
|
+
writable: true,
|
|
88
|
+
value: 128
|
|
89
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class MemoryStorage {
|
|
2
|
+
constructor() {
|
|
3
|
+
Object.defineProperty(this, "values", {
|
|
4
|
+
enumerable: true,
|
|
5
|
+
configurable: true,
|
|
6
|
+
writable: true,
|
|
7
|
+
value: new Map()
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
getItem(key) {
|
|
11
|
+
return this.values.get(key) ?? null;
|
|
12
|
+
}
|
|
13
|
+
setItem(key, value) {
|
|
14
|
+
this.values.set(key, value);
|
|
15
|
+
}
|
|
16
|
+
removeItem(key) {
|
|
17
|
+
this.values.delete(key);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const fallbackStorage = new MemoryStorage();
|
|
21
|
+
export function getDefaultStorage() {
|
|
22
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
23
|
+
return window.localStorage;
|
|
24
|
+
}
|
|
25
|
+
return fallbackStorage;
|
|
26
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@meshagent/meshagent-ts-auth",
|
|
3
|
+
"version": "0.35.6",
|
|
4
|
+
"description": "Meshagent Typescript Auth",
|
|
5
|
+
"homepage": "https://github.com/meshagent/meshagent-ts-auth",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "mkdir -p dist && bash ./scripts/build.sh",
|
|
8
|
+
"test": "jest",
|
|
9
|
+
"test:watch": "jest --watch"
|
|
10
|
+
},
|
|
11
|
+
"author": "Meshagent Software",
|
|
12
|
+
"license": "Apache-2.0",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"unpkg": "./dist/browser/ma-auth.global.js",
|
|
15
|
+
"jsdelivr": "./dist/browser/ma-auth.global.js",
|
|
16
|
+
"module": "dist/esm/index.js",
|
|
17
|
+
"main": "./dist/esm/index.js",
|
|
18
|
+
"types": "dist/esm/index.d.ts",
|
|
19
|
+
"typesVersions": {
|
|
20
|
+
"*": {
|
|
21
|
+
"global": [
|
|
22
|
+
"dist/browser/browser-global.d.ts"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"module": "./dist/esm/index.js",
|
|
29
|
+
"default": "./dist/cjs/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./package.json": "./package.json"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"LICENSE",
|
|
36
|
+
"README.md",
|
|
37
|
+
"CHANGELOG.md"
|
|
38
|
+
],
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@meshagent/meshagent": "^0.35.6",
|
|
41
|
+
"typescript": "^5.8.3"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"esbuild": "^0.25.0",
|
|
45
|
+
"jest": "^30.3.0"
|
|
46
|
+
},
|
|
47
|
+
"overrides": {
|
|
48
|
+
"rollup": "4.52.5"
|
|
49
|
+
}
|
|
50
|
+
}
|