@axa-fr/oidc-client 7.22.18 → 7.22.19
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/README.md +31 -39
- package/bin/copy-service-worker-files.mjs +24 -17
- package/dist/OidcTrustedDomains.js +14 -12
- package/dist/cache.d.ts.map +1 -1
- package/dist/checkSession.d.ts +1 -1
- package/dist/checkSession.d.ts.map +1 -1
- package/dist/checkSessionIFrame.d.ts.map +1 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/fetch.d.ts +2 -1
- package/dist/fetch.d.ts.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +935 -601
- package/dist/index.umd.cjs +2 -2
- package/dist/initSession.d.ts +1 -1
- package/dist/initSession.d.ts.map +1 -1
- package/dist/initWorker.d.ts +2 -2
- package/dist/initWorker.d.ts.map +1 -1
- package/dist/initWorkerOption.d.ts.map +1 -1
- package/dist/jwt.d.ts +2 -2
- package/dist/jwt.d.ts.map +1 -1
- package/dist/keepSession.d.ts.map +1 -1
- package/dist/location.d.ts.map +1 -1
- package/dist/login.d.ts +1 -1
- package/dist/login.d.ts.map +1 -1
- package/dist/logout.d.ts +1 -1
- package/dist/logout.d.ts.map +1 -1
- package/dist/oidc.d.ts +1 -1
- package/dist/oidc.d.ts.map +1 -1
- package/dist/oidcClient.d.ts +2 -2
- package/dist/oidcClient.d.ts.map +1 -1
- package/dist/parseTokens.d.ts.map +1 -1
- package/dist/renewTokens.d.ts.map +1 -1
- package/dist/requests.d.ts +1 -1
- package/dist/requests.d.ts.map +1 -1
- package/dist/silentLogin.d.ts.map +1 -1
- package/dist/timer.d.ts.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/user.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/cache.ts +21 -18
- package/src/checkSession.ts +89 -54
- package/src/checkSessionIFrame.ts +70 -69
- package/src/crypto.ts +27 -25
- package/src/events.ts +28 -28
- package/src/fetch.ts +40 -21
- package/src/index.ts +6 -17
- package/src/iniWorker.spec.ts +26 -16
- package/src/initSession.ts +115 -113
- package/src/initWorker.ts +299 -212
- package/src/initWorkerOption.ts +121 -114
- package/src/jwt.ts +150 -136
- package/src/keepSession.ts +100 -81
- package/src/location.ts +24 -26
- package/src/login.ts +246 -189
- package/src/logout.spec.ts +131 -76
- package/src/logout.ts +130 -115
- package/src/oidc.ts +426 -337
- package/src/oidcClient.ts +129 -105
- package/src/parseTokens.spec.ts +198 -179
- package/src/parseTokens.ts +221 -186
- package/src/renewTokens.ts +397 -284
- package/src/requests.spec.ts +5 -7
- package/src/requests.ts +142 -114
- package/src/route-utils.spec.ts +17 -19
- package/src/route-utils.ts +29 -26
- package/src/silentLogin.ts +145 -127
- package/src/timer.ts +10 -11
- package/src/types.ts +56 -46
- package/src/user.ts +17 -12
- package/src/version.ts +1 -1
package/src/requests.spec.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import { describe, expect,it } from 'vitest';
|
|
3
|
-
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
4
2
|
|
|
5
3
|
describe('Requests test Suite', () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
});
|
|
4
|
+
it('performAuthorizationRequestAsync', async () => {
|
|
5
|
+
expect(true).toBe(true);
|
|
6
|
+
});
|
|
7
|
+
});
|
package/src/requests.ts
CHANGED
|
@@ -1,159 +1,183 @@
|
|
|
1
1
|
import { getFromCache, setCache } from './cache.js';
|
|
2
2
|
import { deriveChallengeAsync, generateRandom } from './crypto.js';
|
|
3
|
+
import { ILOidcLocation } from './location';
|
|
3
4
|
import { OidcAuthorizationServiceConfiguration } from './oidc.js';
|
|
4
5
|
import { parseOriginalTokens } from './parseTokens.js';
|
|
5
6
|
import { Fetch, StringMap } from './types.js';
|
|
6
|
-
import {ILOidcLocation} from "./location";
|
|
7
7
|
|
|
8
8
|
const oneHourSecond = 60 * 60;
|
|
9
|
-
export const fetchFromIssuer =
|
|
10
|
-
|
|
9
|
+
export const fetchFromIssuer =
|
|
10
|
+
fetch =>
|
|
11
|
+
async (
|
|
12
|
+
openIdIssuerUrl: string,
|
|
13
|
+
timeCacheSecond = oneHourSecond,
|
|
14
|
+
storage = window.sessionStorage,
|
|
15
|
+
timeoutMs = 10000,
|
|
16
|
+
): Promise<OidcAuthorizationServiceConfiguration> => {
|
|
11
17
|
const fullUrl = `${openIdIssuerUrl}/.well-known/openid-configuration`;
|
|
12
18
|
|
|
13
19
|
const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
|
|
14
20
|
const data = getFromCache(localStorageKey, storage, timeCacheSecond);
|
|
15
21
|
if (data) {
|
|
16
|
-
|
|
22
|
+
return new OidcAuthorizationServiceConfiguration(data);
|
|
17
23
|
}
|
|
18
24
|
const response = await internalFetch(fetch)(fullUrl, {}, timeoutMs);
|
|
19
25
|
|
|
20
26
|
if (response.status !== 200) {
|
|
21
|
-
|
|
27
|
+
return null;
|
|
22
28
|
}
|
|
23
29
|
|
|
24
30
|
const result = await response.json();
|
|
25
31
|
|
|
26
32
|
setCache(localStorageKey, result, storage);
|
|
27
33
|
return new OidcAuthorizationServiceConfiguration(result);
|
|
28
|
-
};
|
|
34
|
+
};
|
|
29
35
|
|
|
30
|
-
const internalFetch =
|
|
36
|
+
const internalFetch =
|
|
37
|
+
fetch =>
|
|
38
|
+
async (url: string, headers = {}, timeoutMs = 10000, numberRetry = 0): Promise<Response> => {
|
|
31
39
|
let response;
|
|
32
40
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
const controller = new AbortController();
|
|
42
|
+
setTimeout(() => controller.abort(), timeoutMs);
|
|
43
|
+
response = await fetch(url, { ...headers, signal: controller.signal });
|
|
36
44
|
} catch (e: any) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return await internalFetch(fetch)(url, headers, timeoutMs, numberRetry + 1);
|
|
41
|
-
} else {
|
|
42
|
-
throw e;
|
|
43
|
-
}
|
|
45
|
+
if (e.name === 'AbortError' || e.message === 'Network request failed') {
|
|
46
|
+
if (numberRetry <= 1) {
|
|
47
|
+
return await internalFetch(fetch)(url, headers, timeoutMs, numberRetry + 1);
|
|
44
48
|
} else {
|
|
45
|
-
|
|
46
|
-
throw e; // rethrow other unexpected errors
|
|
49
|
+
throw e;
|
|
47
50
|
}
|
|
51
|
+
} else {
|
|
52
|
+
console.error(e.message);
|
|
53
|
+
throw e; // rethrow other unexpected errors
|
|
54
|
+
}
|
|
48
55
|
}
|
|
49
56
|
return response;
|
|
50
|
-
};
|
|
57
|
+
};
|
|
51
58
|
|
|
52
59
|
export const TOKEN_TYPE = {
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
refresh_token: 'refresh_token',
|
|
61
|
+
access_token: 'access_token',
|
|
55
62
|
};
|
|
56
63
|
|
|
57
|
-
export const performRevocationRequestAsync =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
export const performRevocationRequestAsync =
|
|
65
|
+
fetch =>
|
|
66
|
+
async (
|
|
67
|
+
url,
|
|
68
|
+
token,
|
|
69
|
+
token_type = TOKEN_TYPE.refresh_token,
|
|
70
|
+
client_id,
|
|
71
|
+
extras: StringMap = {},
|
|
72
|
+
timeoutMs = 10000,
|
|
73
|
+
) => {
|
|
63
74
|
const details = {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
token,
|
|
76
|
+
token_type_hint: token_type,
|
|
77
|
+
client_id,
|
|
67
78
|
};
|
|
68
79
|
for (const [key, value] of Object.entries(extras)) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
80
|
+
if (details[key] === undefined) {
|
|
81
|
+
details[key] = value;
|
|
82
|
+
}
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
const formBody = [];
|
|
76
86
|
for (const property in details) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
const encodedKey = encodeURIComponent(property);
|
|
88
|
+
const encodedValue = encodeURIComponent(details[property]);
|
|
89
|
+
formBody.push(`${encodedKey}=${encodedValue}`);
|
|
80
90
|
}
|
|
81
91
|
const formBodyString = formBody.join('&');
|
|
82
92
|
|
|
83
|
-
const response = await internalFetch(fetch)(
|
|
93
|
+
const response = await internalFetch(fetch)(
|
|
94
|
+
url,
|
|
95
|
+
{
|
|
84
96
|
method: 'POST',
|
|
85
97
|
headers: {
|
|
86
|
-
|
|
98
|
+
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
87
99
|
},
|
|
88
100
|
body: formBodyString,
|
|
89
|
-
|
|
101
|
+
},
|
|
102
|
+
timeoutMs,
|
|
103
|
+
);
|
|
90
104
|
if (response.status !== 200) {
|
|
91
|
-
|
|
105
|
+
return { success: false };
|
|
92
106
|
}
|
|
93
107
|
return {
|
|
94
|
-
|
|
108
|
+
success: true,
|
|
95
109
|
};
|
|
96
|
-
};
|
|
97
|
-
|
|
110
|
+
};
|
|
98
111
|
|
|
99
112
|
type PerformTokenRequestResponse = {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export const performTokenRequestAsync =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
success: boolean;
|
|
114
|
+
status?: number;
|
|
115
|
+
data?: any;
|
|
116
|
+
demonstratingProofOfPossessionNonce?: string;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const performTokenRequestAsync =
|
|
120
|
+
(fetch: Fetch) =>
|
|
121
|
+
async (
|
|
122
|
+
url: string,
|
|
123
|
+
details,
|
|
124
|
+
extras,
|
|
125
|
+
oldTokens,
|
|
126
|
+
headersExtras = {},
|
|
127
|
+
tokenRenewMode: string,
|
|
128
|
+
timeoutMs = 10000,
|
|
129
|
+
): Promise<PerformTokenRequestResponse> => {
|
|
113
130
|
for (const [key, value] of Object.entries(extras)) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
131
|
+
if (details[key] === undefined) {
|
|
132
|
+
details[key] = value;
|
|
133
|
+
}
|
|
117
134
|
}
|
|
118
135
|
|
|
119
136
|
const formBody = [];
|
|
120
137
|
for (const property in details) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
138
|
+
const encodedKey = encodeURIComponent(property);
|
|
139
|
+
const encodedValue = encodeURIComponent(details[property]);
|
|
140
|
+
formBody.push(`${encodedKey}=${encodedValue}`);
|
|
124
141
|
}
|
|
125
142
|
const formBodyString = formBody.join('&');
|
|
126
|
-
|
|
127
|
-
const response = await internalFetch(fetch)(
|
|
143
|
+
|
|
144
|
+
const response = await internalFetch(fetch)(
|
|
145
|
+
url,
|
|
146
|
+
{
|
|
128
147
|
method: 'POST',
|
|
129
148
|
headers: {
|
|
130
|
-
|
|
131
|
-
|
|
149
|
+
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
150
|
+
...headersExtras,
|
|
132
151
|
},
|
|
133
152
|
body: formBodyString,
|
|
134
|
-
|
|
153
|
+
},
|
|
154
|
+
timeoutMs,
|
|
155
|
+
);
|
|
135
156
|
if (response.status !== 200) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
157
|
+
return {
|
|
158
|
+
success: false,
|
|
159
|
+
status: response.status,
|
|
160
|
+
demonstratingProofOfPossessionNonce: null,
|
|
161
|
+
};
|
|
141
162
|
}
|
|
142
163
|
const tokens = await response.json();
|
|
143
164
|
|
|
144
165
|
let demonstratingProofOfPossessionNonce = null;
|
|
145
|
-
if(
|
|
146
|
-
|
|
166
|
+
if (response.headers.has(demonstratingProofOfPossessionNonceResponseHeader)) {
|
|
167
|
+
demonstratingProofOfPossessionNonce = response.headers.get(
|
|
168
|
+
demonstratingProofOfPossessionNonceResponseHeader,
|
|
169
|
+
);
|
|
147
170
|
}
|
|
148
171
|
return {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
172
|
+
success: true,
|
|
173
|
+
status: response.status,
|
|
174
|
+
data: parseOriginalTokens(tokens, oldTokens, tokenRenewMode),
|
|
175
|
+
demonstratingProofOfPossessionNonce: demonstratingProofOfPossessionNonce,
|
|
153
176
|
};
|
|
154
|
-
};
|
|
177
|
+
};
|
|
155
178
|
|
|
156
|
-
export const performAuthorizationRequestAsync =
|
|
179
|
+
export const performAuthorizationRequestAsync =
|
|
180
|
+
(storage: any, oidcLocation: ILOidcLocation) => async (url, extras: StringMap) => {
|
|
157
181
|
extras = extras ? { ...extras } : {};
|
|
158
182
|
const codeVerifier = generateRandom(128);
|
|
159
183
|
const codeChallenge = await deriveChallengeAsync(codeVerifier);
|
|
@@ -163,56 +187,60 @@ export const performAuthorizationRequestAsync = (storage: any, oidcLocation: ILO
|
|
|
163
187
|
extras.code_challenge_method = 'S256';
|
|
164
188
|
let queryString = '';
|
|
165
189
|
if (extras) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
queryString += `${key}=${encodeURIComponent(value)}`;
|
|
190
|
+
for (const [key, value] of Object.entries(extras)) {
|
|
191
|
+
if (queryString === '') {
|
|
192
|
+
queryString += '?';
|
|
193
|
+
} else {
|
|
194
|
+
queryString += '&';
|
|
173
195
|
}
|
|
196
|
+
queryString += `${key}=${encodeURIComponent(value)}`;
|
|
197
|
+
}
|
|
174
198
|
}
|
|
175
199
|
oidcLocation.open(`${url}${queryString}`);
|
|
176
|
-
};
|
|
200
|
+
};
|
|
177
201
|
|
|
178
|
-
const demonstratingProofOfPossessionNonceResponseHeader =
|
|
179
|
-
export const performFirstTokenRequestAsync =
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
tokenRenewMode: string,
|
|
183
|
-
timeoutMs = 10000) => {
|
|
202
|
+
const demonstratingProofOfPossessionNonceResponseHeader = 'DPoP-Nonce';
|
|
203
|
+
export const performFirstTokenRequestAsync =
|
|
204
|
+
(storage: any) =>
|
|
205
|
+
async (url, formBodyExtras, headersExtras, tokenRenewMode: string, timeoutMs = 10000) => {
|
|
184
206
|
formBodyExtras = formBodyExtras ? { ...formBodyExtras } : {};
|
|
185
207
|
formBodyExtras.code_verifier = await storage.getCodeVerifierAsync();
|
|
186
208
|
const formBody = [];
|
|
187
209
|
for (const property in formBodyExtras) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
210
|
+
const encodedKey = encodeURIComponent(property);
|
|
211
|
+
const encodedValue = encodeURIComponent(formBodyExtras[property]);
|
|
212
|
+
formBody.push(`${encodedKey}=${encodedValue}`);
|
|
191
213
|
}
|
|
192
214
|
const formBodyString = formBody.join('&');
|
|
193
|
-
const response = await internalFetch(fetch)(
|
|
215
|
+
const response = await internalFetch(fetch)(
|
|
216
|
+
url,
|
|
217
|
+
{
|
|
194
218
|
method: 'POST',
|
|
195
219
|
headers: {
|
|
196
|
-
|
|
197
|
-
|
|
220
|
+
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
|
221
|
+
...headersExtras,
|
|
198
222
|
},
|
|
199
223
|
body: formBodyString,
|
|
200
|
-
|
|
224
|
+
},
|
|
225
|
+
timeoutMs,
|
|
226
|
+
);
|
|
201
227
|
await Promise.all([storage.setCodeVerifierAsync(null), storage.setStateAsync(null)]);
|
|
202
228
|
if (response.status !== 200) {
|
|
203
|
-
|
|
229
|
+
return { success: false, status: response.status };
|
|
204
230
|
}
|
|
205
|
-
let demonstratingProofOfPossessionNonce:string= null;
|
|
206
|
-
if(
|
|
207
|
-
|
|
231
|
+
let demonstratingProofOfPossessionNonce: string = null;
|
|
232
|
+
if (response.headers.has(demonstratingProofOfPossessionNonceResponseHeader)) {
|
|
233
|
+
demonstratingProofOfPossessionNonce = response.headers.get(
|
|
234
|
+
demonstratingProofOfPossessionNonceResponseHeader,
|
|
235
|
+
);
|
|
208
236
|
}
|
|
209
237
|
const tokens = await response.json();
|
|
210
238
|
return {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
239
|
+
success: true,
|
|
240
|
+
data: {
|
|
241
|
+
state: formBodyExtras.state,
|
|
242
|
+
tokens: parseOriginalTokens(tokens, null, tokenRenewMode),
|
|
243
|
+
demonstratingProofOfPossessionNonce,
|
|
244
|
+
},
|
|
217
245
|
};
|
|
218
|
-
};
|
|
246
|
+
};
|
package/src/route-utils.spec.ts
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
import { describe, expect,it } from 'vitest';
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
3
|
import { getPath } from './route-utils';
|
|
4
4
|
|
|
5
5
|
describe('Route test Suite', () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
);
|
|
6
|
+
it.each([
|
|
7
|
+
['http://example.com/pathname', '/pathname'],
|
|
8
|
+
['http://example.com:3000/pathname/?search=test#hash', '/pathname#hash'],
|
|
9
|
+
['http://example.com:3000/pathname/#hash?search=test', '/pathname#hash'],
|
|
10
|
+
['http://example.com:3000/pathname#hash?search=test', '/pathname#hash'],
|
|
11
|
+
['capacitor://localhost/index.html', '/index.html'],
|
|
12
|
+
['capacitor://localhost/pathname#hash?search=test', '/pathname#hash'],
|
|
13
|
+
['http://example.com:3000/', ''],
|
|
14
|
+
])('getPath should return the full path of an url', (uri, expected) => {
|
|
15
|
+
const path = getPath(uri);
|
|
16
|
+
expect(path).toBe(expected);
|
|
17
|
+
});
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
19
|
+
it('wrong uri format', () => {
|
|
20
|
+
expect(() => getPath('urimybad/toto.com')).toThrowError();
|
|
21
|
+
});
|
|
22
|
+
});
|
package/src/route-utils.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
export const getLocation = (href: string) => {
|
|
2
2
|
const match = href.match(
|
|
3
3
|
// eslint-disable-next-line no-useless-escape
|
|
4
|
-
|
|
4
|
+
/^([a-z][\w-]+\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/,
|
|
5
5
|
);
|
|
6
6
|
if (!match) {
|
|
7
|
-
|
|
7
|
+
throw new Error('Invalid URL');
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
let search = match[6];
|
|
11
11
|
let hash = match[7];
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
13
|
+
if (hash) {
|
|
14
|
+
const splits = hash.split('?');
|
|
15
|
+
if (splits.length === 2) {
|
|
16
|
+
hash = splits[0];
|
|
17
|
+
search = splits[1];
|
|
19
18
|
}
|
|
19
|
+
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
if (search.startsWith('?')) {
|
|
22
|
+
search = search.slice(1);
|
|
23
|
+
}
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
26
|
match && {
|
|
@@ -41,12 +41,12 @@ export const getPath = (href: string) => {
|
|
|
41
41
|
let { path } = location;
|
|
42
42
|
|
|
43
43
|
if (path.endsWith('/')) {
|
|
44
|
-
|
|
44
|
+
path = path.slice(0, -1);
|
|
45
45
|
}
|
|
46
46
|
let { hash } = location;
|
|
47
47
|
|
|
48
48
|
if (hash === '#_=_') {
|
|
49
|
-
|
|
49
|
+
hash = '';
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
if (hash) {
|
|
@@ -57,23 +57,26 @@ export const getPath = (href: string) => {
|
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
export const getParseQueryStringFromLocation = (href: string) => {
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
const location = getLocation(href);
|
|
61
|
+
const { search } = location;
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
return parseQueryString(search);
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
const parseQueryString = (queryString:string) => {
|
|
67
|
-
|
|
66
|
+
const parseQueryString = (queryString: string) => {
|
|
67
|
+
const params: any = {};
|
|
68
|
+
let temp;
|
|
69
|
+
let i;
|
|
70
|
+
let l;
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
// Split into key/value pairs
|
|
73
|
+
const queries = queryString.split('&');
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
// Convert the array of strings into an object
|
|
76
|
+
for (i = 0, l = queries.length; i < l; i++) {
|
|
77
|
+
temp = queries[i].split('=');
|
|
78
|
+
params[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]);
|
|
79
|
+
}
|
|
77
80
|
|
|
78
|
-
|
|
81
|
+
return params;
|
|
79
82
|
};
|