@axa-fr/oidc-client-service-worker 7.9.3-alpha.1132 → 7.9.3
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/OidcServiceWorker.js +51 -74
- package/dist/OidcServiceWorker.js.map +1 -1
- package/dist/src/utils/__tests__/normalizeUrl.spec.d.ts +2 -0
- package/dist/src/utils/__tests__/normalizeUrl.spec.d.ts.map +1 -0
- package/dist/src/utils/domains.d.ts +0 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/normalizeUrl.d.ts +1 -0
- package/dist/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/OidcServiceWorker.ts +442 -401
- package/src/utils/__tests__/domains.spec.ts +33 -61
- package/src/utils/__tests__/normalizeUrl.spec.ts +28 -0
- package/src/utils/domains.ts +3 -86
- package/src/utils/index.ts +1 -0
- package/src/utils/normalizeUrl.ts +9 -0
- package/src/version.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
1
|
+
import { beforeEach, describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
3
|
import { openidWellknownUrlEndWith } from '../../constants';
|
|
4
|
-
import { checkDomain, getCurrentDatabaseDomain
|
|
4
|
+
import { checkDomain, getCurrentDatabaseDomain } from '..';
|
|
5
5
|
import { Database, Tokens, TrustedDomains } from './../../types';
|
|
6
6
|
|
|
7
7
|
describe('domains', () => {
|
|
@@ -30,28 +30,32 @@ describe('domains', () => {
|
|
|
30
30
|
});
|
|
31
31
|
});
|
|
32
32
|
describe('getCurrentDatabaseDomain', () => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
let db: Database;
|
|
34
|
+
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
db = {
|
|
37
|
+
default: {
|
|
38
|
+
configurationName: 'config',
|
|
39
|
+
tokens: {} as Tokens,
|
|
40
|
+
status: 'NOT_CONNECTED',
|
|
41
|
+
state: null,
|
|
42
|
+
codeVerifier: null,
|
|
43
|
+
nonce: null,
|
|
44
|
+
oidcServerConfiguration: {
|
|
45
|
+
authorizationEndpoint: 'https://demo.duendesoftware.com/connect/authorize',
|
|
46
|
+
issuer: 'https://demo.duendesoftware.com',
|
|
47
|
+
revocationEndpoint: 'https://demo.duendesoftware.com/connect/revocation',
|
|
48
|
+
tokenEndpoint: 'https://demo.duendesoftware.com/connect/token',
|
|
49
|
+
userInfoEndpoint: 'https://demo.duendesoftware.com/connect/userinfo',
|
|
50
|
+
},
|
|
51
|
+
hideAccessToken: true,
|
|
52
|
+
convertAllRequestsToCorsExceptNavigate: false,
|
|
53
|
+
setAccessTokenToNavigateRequests: true,
|
|
54
|
+
demonstratingProofOfPossessionNonce: null,
|
|
55
|
+
demonstratingProofOfPossessionJwkJson: null,
|
|
47
56
|
},
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
setAccessTokenToNavigateRequests: true,
|
|
51
|
-
demonstratingProofOfPossessionNonce: null,
|
|
52
|
-
demonstratingProofOfPossessionJwkJson: null,
|
|
53
|
-
},
|
|
54
|
-
};
|
|
57
|
+
};
|
|
58
|
+
});
|
|
55
59
|
|
|
56
60
|
it('will return null when url ends with openidWellknownUrlEndWith', () => {
|
|
57
61
|
const trustedDomains: TrustedDomains = {
|
|
@@ -69,15 +73,18 @@ describe('domains', () => {
|
|
|
69
73
|
expect(getCurrentDatabaseDomain(db, url, trustedDomains)).toBeNull();
|
|
70
74
|
});
|
|
71
75
|
|
|
72
|
-
it('will return null when url is the token endpoint
|
|
76
|
+
it('will return null when url is the token endpoint oidc config token endpoint has a default port', () => {
|
|
73
77
|
const trustedDomains: TrustedDomains = {
|
|
74
78
|
default: ['https://demo.duendesoftware.com', 'https://kdhttps.auth0.com'],
|
|
75
79
|
};
|
|
76
|
-
|
|
80
|
+
db['default'].oidcServerConfiguration!.tokenEndpoint =
|
|
81
|
+
'https://demo.duendesoftware.com:443/connect/token';
|
|
82
|
+
|
|
83
|
+
const url = 'https://demo.duendesoftware.com/connect/token';
|
|
77
84
|
expect(getCurrentDatabaseDomain(db, url, trustedDomains)).toBeNull();
|
|
78
85
|
});
|
|
79
86
|
|
|
80
|
-
it('will return null when url is the
|
|
87
|
+
it('will return null when url is the revocation endpoint', () => {
|
|
81
88
|
const trustedDomains: TrustedDomains = {
|
|
82
89
|
default: ['https://demo.duendesoftware.com', 'https://kdhttps.auth0.com'],
|
|
83
90
|
};
|
|
@@ -117,39 +124,4 @@ describe('domains', () => {
|
|
|
117
124
|
expect(getCurrentDatabaseDomain(db, 'https://domain/test', trustedDomains)).toBeNull();
|
|
118
125
|
});
|
|
119
126
|
});
|
|
120
|
-
it('normalizes urls', () => {
|
|
121
|
-
expect(normalizeUrl('foo.com')).toBe('https://foo.com');
|
|
122
|
-
expect(normalizeUrl('foo.com ')).toBe('https://foo.com');
|
|
123
|
-
expect(normalizeUrl('foo.com.')).toBe('https://foo.com');
|
|
124
|
-
expect(normalizeUrl('foo.com')).toBe('https://foo.com');
|
|
125
|
-
expect(normalizeUrl('HTTP://foo.com')).toBe('http://foo.com');
|
|
126
|
-
expect(normalizeUrl('//foo.com')).toBe('https://foo.com');
|
|
127
|
-
expect(normalizeUrl('http://foo.com')).toBe('http://foo.com');
|
|
128
|
-
expect(normalizeUrl('http://foo.com:80')).toBe('http://foo.com');
|
|
129
|
-
expect(normalizeUrl('https://foo.com:443')).toBe('https://foo.com');
|
|
130
|
-
expect(normalizeUrl('http://foo.com/foo/')).toBe('http://foo.com/foo');
|
|
131
|
-
expect(normalizeUrl('foo.com/?foo=bar baz')).toBe('https://foo.com/?foo=bar+baz');
|
|
132
|
-
expect(normalizeUrl('https://foo.com/https://bar.com')).toBe('https://foo.com/https://bar.com');
|
|
133
|
-
expect(normalizeUrl('https://foo.com/https://bar.com/foo//bar')).toBe(
|
|
134
|
-
'https://foo.com/https://bar.com/foo/bar',
|
|
135
|
-
);
|
|
136
|
-
expect(normalizeUrl('https://foo.com/http://bar.com')).toBe('https://foo.com/http://bar.com');
|
|
137
|
-
expect(normalizeUrl('https://foo.com/http://bar.com/foo//bar')).toBe(
|
|
138
|
-
'https://foo.com/http://bar.com/foo/bar',
|
|
139
|
-
);
|
|
140
|
-
expect(normalizeUrl('http://foo.com/%7Efoo/')).toBe('http://foo.com/~foo');
|
|
141
|
-
expect(normalizeUrl('https://foo.com/%FAIL%/07/94/ca/55.jpg')).toBe(
|
|
142
|
-
'https://foo.com/%FAIL%/07/94/ca/55.jpg',
|
|
143
|
-
);
|
|
144
|
-
expect(normalizeUrl('http://foo.com/?')).toBe('http://foo.com');
|
|
145
|
-
expect(normalizeUrl('êxample.com')).toBe('https://xn--xample-hva.com');
|
|
146
|
-
expect(normalizeUrl('http://foo.com/?b=bar&a=foo')).toBe('http://foo.com/?a=foo&b=bar');
|
|
147
|
-
expect(normalizeUrl('http://foo.com/?foo=bar*|<>:"')).toBe(
|
|
148
|
-
'http://foo.com/?foo=bar*|%3C%3E:%22',
|
|
149
|
-
);
|
|
150
|
-
expect(normalizeUrl('http://foo.com:5000')).toBe('http://foo.com:5000');
|
|
151
|
-
expect(normalizeUrl('http://foo.com/foo#bar')).toBe('http://foo.com/foo#bar');
|
|
152
|
-
expect(normalizeUrl('http://foo.com/foo/bar/../baz')).toBe('http://foo.com/foo/baz');
|
|
153
|
-
expect(normalizeUrl('http://foo.com/foo/bar/./baz')).toBe('http://foo.com/foo/bar/baz');
|
|
154
|
-
});
|
|
155
127
|
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { normalizeUrl } from '../normalizeUrl';
|
|
4
|
+
|
|
5
|
+
describe('normalizeUrl', () => {
|
|
6
|
+
it('keeps urls the same', () => {
|
|
7
|
+
expect(normalizeUrl('http://foo.com/')).toBe('http://foo.com/');
|
|
8
|
+
expect(normalizeUrl('https://foo.com/')).toBe('https://foo.com/');
|
|
9
|
+
});
|
|
10
|
+
it('adds slashes', () => {
|
|
11
|
+
expect(normalizeUrl('http://foo.com')).toBe('http://foo.com/');
|
|
12
|
+
});
|
|
13
|
+
it('removes port numbers', () => {
|
|
14
|
+
expect(normalizeUrl('http://foo.com:80/')).toBe('http://foo.com/');
|
|
15
|
+
expect(normalizeUrl('https://foo.com:443/')).toBe('https://foo.com/');
|
|
16
|
+
});
|
|
17
|
+
it('removed port numbers and adds slashes', () => {
|
|
18
|
+
expect(normalizeUrl('http://foo.com:80')).toBe('http://foo.com/');
|
|
19
|
+
expect(normalizeUrl('https://foo.com:443')).toBe('https://foo.com/');
|
|
20
|
+
});
|
|
21
|
+
it('lowercases urls', () => {
|
|
22
|
+
expect(normalizeUrl('http://FOO.com/')).toBe('http://foo.com/');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('keeps invalid urls', () => {
|
|
26
|
+
expect(normalizeUrl('foo')).toBe('foo');
|
|
27
|
+
});
|
|
28
|
+
});
|
package/src/utils/domains.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { acceptAnyDomainToken, openidWellknownUrlEndWith, scriptFilename } from '../constants';
|
|
2
2
|
import { Database, Domain, DomainDetails, OidcConfig, TrustedDomains } from '../types';
|
|
3
|
+
import { normalizeUrl } from './normalizeUrl';
|
|
3
4
|
|
|
4
5
|
export function checkDomain(domains: Domain[], endpoint: string) {
|
|
5
6
|
if (!endpoint) {
|
|
@@ -52,13 +53,13 @@ export const getCurrentDatabaseDomain = (
|
|
|
52
53
|
|
|
53
54
|
if (
|
|
54
55
|
oidcServerConfiguration.tokenEndpoint &&
|
|
55
|
-
|
|
56
|
+
url === normalizeUrl(oidcServerConfiguration.tokenEndpoint)
|
|
56
57
|
) {
|
|
57
58
|
continue;
|
|
58
59
|
}
|
|
59
60
|
if (
|
|
60
61
|
oidcServerConfiguration.revocationEndpoint &&
|
|
61
|
-
|
|
62
|
+
url === normalizeUrl(oidcServerConfiguration.revocationEndpoint)
|
|
62
63
|
) {
|
|
63
64
|
continue;
|
|
64
65
|
}
|
|
@@ -96,87 +97,3 @@ export const getCurrentDatabaseDomain = (
|
|
|
96
97
|
}
|
|
97
98
|
return null;
|
|
98
99
|
};
|
|
99
|
-
|
|
100
|
-
export function normalizeUrl(url: string) {
|
|
101
|
-
url = url.trim();
|
|
102
|
-
|
|
103
|
-
const hasRelativeProtocol = url.startsWith('//');
|
|
104
|
-
const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(url);
|
|
105
|
-
|
|
106
|
-
// Prepend protocol
|
|
107
|
-
if (!isRelativeUrl) {
|
|
108
|
-
url = url.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, 'https:');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const urlObject = new URL(url);
|
|
112
|
-
|
|
113
|
-
// Remove duplicate slashes if not preceded by a protocol
|
|
114
|
-
// NOTE: This could be implemented using a single negative lookbehind
|
|
115
|
-
// regex, but we avoid that to maintain compatibility with older js engines
|
|
116
|
-
// which do not have support for that feature.
|
|
117
|
-
if (urlObject.pathname) {
|
|
118
|
-
// Split the string by occurrences of this protocol regex, and perform
|
|
119
|
-
// duplicate-slash replacement on the strings between those occurrences
|
|
120
|
-
// (if any).
|
|
121
|
-
const protocolRegex = /\b[a-z][a-z\d+\-.]{1,50}:\/\//g;
|
|
122
|
-
|
|
123
|
-
let lastIndex = 0;
|
|
124
|
-
let result = '';
|
|
125
|
-
for (;;) {
|
|
126
|
-
const match = protocolRegex.exec(urlObject.pathname);
|
|
127
|
-
if (!match) {
|
|
128
|
-
break;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const protocol = match[0];
|
|
132
|
-
const protocolAtIndex = match.index;
|
|
133
|
-
const intermediate = urlObject.pathname.slice(lastIndex, protocolAtIndex);
|
|
134
|
-
|
|
135
|
-
result += intermediate.replace(/\/{2,}/g, '/');
|
|
136
|
-
result += protocol;
|
|
137
|
-
lastIndex = protocolAtIndex + protocol.length;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const remnant = urlObject.pathname.slice(lastIndex, urlObject.pathname.length);
|
|
141
|
-
result += remnant.replace(/\/{2,}/g, '/');
|
|
142
|
-
|
|
143
|
-
urlObject.pathname = result;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Decode URI octets
|
|
147
|
-
if (urlObject.pathname) {
|
|
148
|
-
try {
|
|
149
|
-
urlObject.pathname = decodeURI(urlObject.pathname);
|
|
150
|
-
} catch {
|
|
151
|
-
/* empty */
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
if (urlObject.hostname) {
|
|
156
|
-
// Remove trailing dot
|
|
157
|
-
urlObject.hostname = urlObject.hostname.replace(/\.$/, '');
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Sort query parameters
|
|
161
|
-
urlObject.searchParams.sort();
|
|
162
|
-
|
|
163
|
-
// Calling `.sort()` encodes the search parameters, so we need to decode them again.
|
|
164
|
-
try {
|
|
165
|
-
urlObject.search = decodeURIComponent(urlObject.search);
|
|
166
|
-
} catch {
|
|
167
|
-
/* empty */
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Remove trailing slash
|
|
171
|
-
urlObject.pathname = urlObject.pathname.replace(/\/$/, '');
|
|
172
|
-
|
|
173
|
-
// Take advantage of many of the Node `url` normalizations
|
|
174
|
-
url = urlObject.toString();
|
|
175
|
-
|
|
176
|
-
// Remove ending `/` unless removeSingleSlash is false
|
|
177
|
-
if (urlObject.hash === '') {
|
|
178
|
-
url = url.replace(/\/$/, '');
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return url;
|
|
182
|
-
}
|
package/src/utils/index.ts
CHANGED
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '7.9.3
|
|
1
|
+
export default '7.9.3';
|