@inrupt/solid-client-authn-browser 1.11.7 → 1.11.8-alpha.0
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/Session.d.ts +0 -1
- package/dist/Session.js +2 -45
- package/dist/Session.js.map +1 -1
- package/dist/login/oidc/redirectHandler/AuthCodeRedirectHandler.d.ts +0 -1
- package/dist/login/oidc/redirectHandler/AuthCodeRedirectHandler.js +1 -23
- package/dist/login/oidc/redirectHandler/AuthCodeRedirectHandler.js.map +1 -1
- package/dist/sessionInfo/SessionInfoManager.js +0 -8
- package/dist/sessionInfo/SessionInfoManager.js.map +1 -1
- package/dist/solid-client-authn.bundle.js +1 -1
- package/examples/demoClientApp/package-lock.json +18 -18
- package/examples/single/bundle/package-lock.json +18 -18
- package/jest.config.js +4 -0
- package/package.json +7 -22
- package/src/Session.spec.ts +0 -224
- package/src/Session.ts +8 -88
- package/src/login/oidc/__mocks__/Redirector.ts +9 -9
- package/src/login/oidc/oidcHandlers/AuthorizationCodeWithPkceOidcHandler.spec.ts +41 -18
- package/src/login/oidc/redirectHandler/AuthCodeRedirectHandler.spec.ts +3 -171
- package/src/login/oidc/redirectHandler/AuthCodeRedirectHandler.ts +0 -68
- package/src/sessionInfo/SessionInfoManager.spec.ts +0 -27
- package/src/sessionInfo/SessionInfoManager.ts +0 -10
|
@@ -2274,9 +2274,9 @@
|
|
|
2274
2274
|
}
|
|
2275
2275
|
},
|
|
2276
2276
|
"node_modules/async": {
|
|
2277
|
-
"version": "2.6.
|
|
2278
|
-
"resolved": "https://registry.npmjs.org/async/-/async-2.6.
|
|
2279
|
-
"integrity": "sha512-
|
|
2277
|
+
"version": "2.6.4",
|
|
2278
|
+
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
|
2279
|
+
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
|
2280
2280
|
"dev": true,
|
|
2281
2281
|
"dependencies": {
|
|
2282
2282
|
"lodash": "^4.17.14"
|
|
@@ -4524,9 +4524,9 @@
|
|
|
4524
4524
|
}
|
|
4525
4525
|
},
|
|
4526
4526
|
"node_modules/minimist": {
|
|
4527
|
-
"version": "1.2.
|
|
4528
|
-
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.
|
|
4529
|
-
"integrity": "sha512-
|
|
4527
|
+
"version": "1.2.6",
|
|
4528
|
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
|
4529
|
+
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
|
4530
4530
|
"dev": true
|
|
4531
4531
|
},
|
|
4532
4532
|
"node_modules/mkdirp": {
|
|
@@ -4598,9 +4598,9 @@
|
|
|
4598
4598
|
"dev": true
|
|
4599
4599
|
},
|
|
4600
4600
|
"node_modules/node-forge": {
|
|
4601
|
-
"version": "1.
|
|
4602
|
-
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.
|
|
4603
|
-
"integrity": "sha512-
|
|
4601
|
+
"version": "1.3.0",
|
|
4602
|
+
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz",
|
|
4603
|
+
"integrity": "sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==",
|
|
4604
4604
|
"dev": true,
|
|
4605
4605
|
"engines": {
|
|
4606
4606
|
"node": ">= 6.13.0"
|
|
@@ -8310,9 +8310,9 @@
|
|
|
8310
8310
|
"dev": true
|
|
8311
8311
|
},
|
|
8312
8312
|
"async": {
|
|
8313
|
-
"version": "2.6.
|
|
8314
|
-
"resolved": "https://registry.npmjs.org/async/-/async-2.6.
|
|
8315
|
-
"integrity": "sha512-
|
|
8313
|
+
"version": "2.6.4",
|
|
8314
|
+
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
|
8315
|
+
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
|
8316
8316
|
"dev": true,
|
|
8317
8317
|
"requires": {
|
|
8318
8318
|
"lodash": "^4.17.14"
|
|
@@ -10044,9 +10044,9 @@
|
|
|
10044
10044
|
}
|
|
10045
10045
|
},
|
|
10046
10046
|
"minimist": {
|
|
10047
|
-
"version": "1.2.
|
|
10048
|
-
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.
|
|
10049
|
-
"integrity": "sha512-
|
|
10047
|
+
"version": "1.2.6",
|
|
10048
|
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
|
10049
|
+
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
|
10050
10050
|
"dev": true
|
|
10051
10051
|
},
|
|
10052
10052
|
"mkdirp": {
|
|
@@ -10111,9 +10111,9 @@
|
|
|
10111
10111
|
}
|
|
10112
10112
|
},
|
|
10113
10113
|
"node-forge": {
|
|
10114
|
-
"version": "1.
|
|
10115
|
-
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.
|
|
10116
|
-
"integrity": "sha512-
|
|
10114
|
+
"version": "1.3.0",
|
|
10115
|
+
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz",
|
|
10116
|
+
"integrity": "sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==",
|
|
10117
10117
|
"dev": true
|
|
10118
10118
|
},
|
|
10119
10119
|
"node-releases": {
|
|
@@ -2266,9 +2266,9 @@
|
|
|
2266
2266
|
}
|
|
2267
2267
|
},
|
|
2268
2268
|
"node_modules/async": {
|
|
2269
|
-
"version": "2.6.
|
|
2270
|
-
"resolved": "https://registry.npmjs.org/async/-/async-2.6.
|
|
2271
|
-
"integrity": "sha512-
|
|
2269
|
+
"version": "2.6.4",
|
|
2270
|
+
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
|
2271
|
+
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
|
2272
2272
|
"dev": true,
|
|
2273
2273
|
"dependencies": {
|
|
2274
2274
|
"lodash": "^4.17.14"
|
|
@@ -4461,9 +4461,9 @@
|
|
|
4461
4461
|
}
|
|
4462
4462
|
},
|
|
4463
4463
|
"node_modules/minimist": {
|
|
4464
|
-
"version": "1.2.
|
|
4465
|
-
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.
|
|
4466
|
-
"integrity": "sha512-
|
|
4464
|
+
"version": "1.2.6",
|
|
4465
|
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
|
4466
|
+
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
|
4467
4467
|
"dev": true
|
|
4468
4468
|
},
|
|
4469
4469
|
"node_modules/mkdirp": {
|
|
@@ -4529,9 +4529,9 @@
|
|
|
4529
4529
|
}
|
|
4530
4530
|
},
|
|
4531
4531
|
"node_modules/node-forge": {
|
|
4532
|
-
"version": "1.
|
|
4533
|
-
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.
|
|
4534
|
-
"integrity": "sha512-
|
|
4532
|
+
"version": "1.3.0",
|
|
4533
|
+
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz",
|
|
4534
|
+
"integrity": "sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==",
|
|
4535
4535
|
"dev": true,
|
|
4536
4536
|
"engines": {
|
|
4537
4537
|
"node": ">= 6.13.0"
|
|
@@ -8059,9 +8059,9 @@
|
|
|
8059
8059
|
"dev": true
|
|
8060
8060
|
},
|
|
8061
8061
|
"async": {
|
|
8062
|
-
"version": "2.6.
|
|
8063
|
-
"resolved": "https://registry.npmjs.org/async/-/async-2.6.
|
|
8064
|
-
"integrity": "sha512-
|
|
8062
|
+
"version": "2.6.4",
|
|
8063
|
+
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
|
8064
|
+
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
|
8065
8065
|
"dev": true,
|
|
8066
8066
|
"requires": {
|
|
8067
8067
|
"lodash": "^4.17.14"
|
|
@@ -9735,9 +9735,9 @@
|
|
|
9735
9735
|
}
|
|
9736
9736
|
},
|
|
9737
9737
|
"minimist": {
|
|
9738
|
-
"version": "1.2.
|
|
9739
|
-
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.
|
|
9740
|
-
"integrity": "sha512-
|
|
9738
|
+
"version": "1.2.6",
|
|
9739
|
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
|
9740
|
+
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
|
9741
9741
|
"dev": true
|
|
9742
9742
|
},
|
|
9743
9743
|
"mkdirp": {
|
|
@@ -9794,9 +9794,9 @@
|
|
|
9794
9794
|
}
|
|
9795
9795
|
},
|
|
9796
9796
|
"node-forge": {
|
|
9797
|
-
"version": "1.
|
|
9798
|
-
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.
|
|
9799
|
-
"integrity": "sha512-
|
|
9797
|
+
"version": "1.3.0",
|
|
9798
|
+
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz",
|
|
9799
|
+
"integrity": "sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==",
|
|
9800
9800
|
"dev": true
|
|
9801
9801
|
},
|
|
9802
9802
|
"node-releases": {
|
package/jest.config.js
CHANGED
|
@@ -2,4 +2,8 @@ module.exports = {
|
|
|
2
2
|
...require("../../jest.config"),
|
|
3
3
|
// Allows running tests from packages/browser/
|
|
4
4
|
testEnvironment: "<rootDir>/../../tests/environment/customEnvironment.js",
|
|
5
|
+
|
|
6
|
+
// Enable injectGlobals here to support jest-mock-console
|
|
7
|
+
// https://github.com/bpedersen/jest-mock-console/issues/32
|
|
8
|
+
injectGlobals: true,
|
|
5
9
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inrupt/solid-client-authn-browser",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.8-alpha.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"types": "dist/index",
|
|
6
6
|
"browser": "dist/index.js",
|
|
@@ -23,38 +23,23 @@
|
|
|
23
23
|
"lint:prettier": "prettier \"src/*.{ts,tsx,js,jsx,css}\" \"**/*.{md,mdx,yml}\"",
|
|
24
24
|
"licenses:check": "license-checker --production --out license.csv --failOn \"AGPL-1.0-only; AGPL-1.0-or-later; AGPL-3.0-only; AGPL-3.0-or-later; Beerware; CC-BY-NC-1.0; CC-BY-NC-2.0; CC-BY-NC-2.5; CC-BY-NC-3.0; CC-BY-NC-4.0; CC-BY-NC-ND-1.0; CC-BY-NC-ND-2.0; CC-BY-NC-ND-2.5; CC-BY-NC-ND-3.0; CC-BY-NC-ND-4.0; CC-BY-NC-SA-1.0; CC-BY-NC-SA-2.0; CC-BY-NC-SA-2.5; CC-BY-NC-SA-3.0; CC-BY-NC-SA-4.0; CPAL-1.0; EUPL-1.0; EUPL-1.1; EUPL-1.1; GPL-1.0-only; GPL-1.0-or-later; GPL-2.0-only; GPL-2.0-or-later; GPL-3.0; GPL-3.0-only; GPL-3.0-or-later; SISSL; SISSL-1.2; WTFPL\"",
|
|
25
25
|
"test": "jest --coverage --verbose",
|
|
26
|
-
"
|
|
26
|
+
"test:debug": "node --inspect-brk ../../node_modules/.bin/jest -i",
|
|
27
|
+
"build-api-docs": "typedoc --out docs/api/source/api --readme none",
|
|
27
28
|
"build-docs-preview-site": "npm run build-api-docs; cd docs/api; make html"
|
|
28
29
|
},
|
|
29
|
-
"devDependencies": {
|
|
30
|
-
"@types/jest": "^27.0.3",
|
|
31
|
-
"cross-fetch": "^3.0.6",
|
|
32
|
-
"eslint": "^7.16.0",
|
|
33
|
-
"jest": "^27.5.1",
|
|
34
|
-
"license-checker": "^25.0.1",
|
|
35
|
-
"ts-jest": "^27.0.7",
|
|
36
|
-
"ts-loader": "^9.1.1",
|
|
37
|
-
"tsc-watch": "^4.2.9",
|
|
38
|
-
"typedoc": "^0.22.4",
|
|
39
|
-
"typedoc-plugin-markdown": "^3.10.2",
|
|
40
|
-
"typescript": "^4.0.5",
|
|
41
|
-
"webpack": "^5.11.0",
|
|
42
|
-
"webpack-cli": "^4.2.0",
|
|
43
|
-
"webpack-merge": "^5.7.2"
|
|
44
|
-
},
|
|
45
30
|
"dependencies": {
|
|
46
|
-
"@inrupt/oidc-client-ext": "^1.11.
|
|
47
|
-
"@inrupt/solid-client-authn-core": "^1.11.
|
|
31
|
+
"@inrupt/oidc-client-ext": "^1.11.8-alpha.0",
|
|
32
|
+
"@inrupt/solid-client-authn-core": "^1.11.8-alpha.0",
|
|
48
33
|
"@types/lodash.clonedeep": "^4.5.6",
|
|
49
34
|
"@types/node": "^17.0.2",
|
|
50
35
|
"@types/uuid": "^8.3.0",
|
|
51
36
|
"events": "^3.3.0",
|
|
52
37
|
"jose": "^4.3.7",
|
|
53
38
|
"lodash.clonedeep": "^4.5.0",
|
|
54
|
-
"uuid": "^8.3.
|
|
39
|
+
"uuid": "^8.3.2"
|
|
55
40
|
},
|
|
56
41
|
"publishConfig": {
|
|
57
42
|
"access": "public"
|
|
58
43
|
},
|
|
59
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "b0642458b3781d66655807781cf53f53a6aa70a9"
|
|
60
45
|
}
|
package/src/Session.spec.ts
CHANGED
|
@@ -395,230 +395,6 @@ describe("Session", () => {
|
|
|
395
395
|
expect(incomingRedirectHandler).toHaveBeenCalled();
|
|
396
396
|
});
|
|
397
397
|
|
|
398
|
-
// This workaround will be removed after we've settled on an API that allows us to silently
|
|
399
|
-
// re-activate the user's session after a refresh:
|
|
400
|
-
describe("(using the temporary workaround for losing a session after refresh)", () => {
|
|
401
|
-
it("does not report the user to be logged in when the workaround cookie is not present, and just executes the redirect", async () => {
|
|
402
|
-
const clientAuthentication = mockClientAuthentication();
|
|
403
|
-
clientAuthentication.handleIncomingRedirect = jest.fn(
|
|
404
|
-
async (_url: string) => undefined
|
|
405
|
-
);
|
|
406
|
-
const mySession = new Session({ clientAuthentication });
|
|
407
|
-
await mySession.handleIncomingRedirect({
|
|
408
|
-
url: "https://some.url",
|
|
409
|
-
useEssSession: true,
|
|
410
|
-
});
|
|
411
|
-
expect(mySession.info.isLoggedIn).toBe(false);
|
|
412
|
-
expect(mySession.info.webId).toBeUndefined();
|
|
413
|
-
expect(
|
|
414
|
-
clientAuthentication.handleIncomingRedirect
|
|
415
|
-
).toHaveBeenCalledTimes(1);
|
|
416
|
-
// The workaround should be enabled by default
|
|
417
|
-
expect(
|
|
418
|
-
window.localStorage.getItem("tmp-resource-server-session-enabled")
|
|
419
|
-
).toBe("true");
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
it("re-initialises the user's WebID without redirection if the proper cookie is set", async () => {
|
|
423
|
-
mockLocalStorage({
|
|
424
|
-
"tmp-resource-server-session-info": JSON.stringify({
|
|
425
|
-
webId: "https://my.pod/profile#me",
|
|
426
|
-
sessions: {
|
|
427
|
-
"https://my.pod/": { expiration: 9000000000000 },
|
|
428
|
-
},
|
|
429
|
-
}),
|
|
430
|
-
});
|
|
431
|
-
const clientAuthentication = mockClientAuthentication();
|
|
432
|
-
clientAuthentication.handleIncomingRedirect = jest.fn();
|
|
433
|
-
const mySession = new Session({ clientAuthentication });
|
|
434
|
-
await mySession.handleIncomingRedirect({
|
|
435
|
-
url: "https://some.url",
|
|
436
|
-
useEssSession: true,
|
|
437
|
-
});
|
|
438
|
-
expect(mySession.info.isLoggedIn).toBe(true);
|
|
439
|
-
expect(mySession.info.webId).toBe("https://my.pod/profile#me");
|
|
440
|
-
expect(
|
|
441
|
-
clientAuthentication.handleIncomingRedirect
|
|
442
|
-
).toHaveBeenCalledTimes(0);
|
|
443
|
-
// The workaround should be enabled by default
|
|
444
|
-
expect(
|
|
445
|
-
window.localStorage.getItem("tmp-resource-server-session-enabled")
|
|
446
|
-
).toBe("true");
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
it("does not attempt to use the workaround if the long-term solution (silent refresh) is enabled", async () => {
|
|
450
|
-
mockLocalStorage({
|
|
451
|
-
"tmp-resource-server-session-info": JSON.stringify({
|
|
452
|
-
webId: "https://my.pod/profile#me",
|
|
453
|
-
sessions: {
|
|
454
|
-
"https://my.pod/": { expiration: 9000000000000 },
|
|
455
|
-
},
|
|
456
|
-
}),
|
|
457
|
-
});
|
|
458
|
-
const clientAuthentication = mockClientAuthentication();
|
|
459
|
-
clientAuthentication.handleIncomingRedirect = jest.fn();
|
|
460
|
-
const mySession = new Session({ clientAuthentication });
|
|
461
|
-
await mySession.handleIncomingRedirect({
|
|
462
|
-
url: "https://some.url",
|
|
463
|
-
restorePreviousSession: true,
|
|
464
|
-
});
|
|
465
|
-
expect(mySession.info.isLoggedIn).toBe(false);
|
|
466
|
-
expect(mySession.info.webId).toBeUndefined();
|
|
467
|
-
expect(
|
|
468
|
-
clientAuthentication.handleIncomingRedirect
|
|
469
|
-
).toHaveBeenCalledTimes(1);
|
|
470
|
-
expect(
|
|
471
|
-
window.localStorage.getItem("tmp-resource-server-session-enabled")
|
|
472
|
-
).toBe("false");
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
it("overrides the workaround if both silent refresh and the ESS session are enabled", async () => {
|
|
476
|
-
mockLocalStorage({
|
|
477
|
-
"tmp-resource-server-session-info": JSON.stringify({
|
|
478
|
-
webId: "https://my.pod/profile#me",
|
|
479
|
-
sessions: {
|
|
480
|
-
"https://my.pod/": { expiration: 9000000000000 },
|
|
481
|
-
},
|
|
482
|
-
}),
|
|
483
|
-
});
|
|
484
|
-
const clientAuthentication = mockClientAuthentication();
|
|
485
|
-
clientAuthentication.handleIncomingRedirect = jest.fn();
|
|
486
|
-
const mySession = new Session({ clientAuthentication });
|
|
487
|
-
await mySession.handleIncomingRedirect({
|
|
488
|
-
url: "https://some.url",
|
|
489
|
-
restorePreviousSession: true,
|
|
490
|
-
useEssSession: true,
|
|
491
|
-
});
|
|
492
|
-
expect(mySession.info.isLoggedIn).toBe(false);
|
|
493
|
-
expect(mySession.info.webId).toBeUndefined();
|
|
494
|
-
expect(
|
|
495
|
-
clientAuthentication.handleIncomingRedirect
|
|
496
|
-
).toHaveBeenCalledTimes(1);
|
|
497
|
-
expect(
|
|
498
|
-
window.localStorage.getItem("tmp-resource-server-session-enabled")
|
|
499
|
-
).toBe("false");
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
it("does not attempt to use the workaround if it is not explicitly enabled", async () => {
|
|
503
|
-
mockLocalStorage({
|
|
504
|
-
"tmp-resource-server-session-info": JSON.stringify({
|
|
505
|
-
webId: "https://my.pod/profile#me",
|
|
506
|
-
sessions: {
|
|
507
|
-
"https://my.pod/": { expiration: 9000000000000 },
|
|
508
|
-
},
|
|
509
|
-
}),
|
|
510
|
-
});
|
|
511
|
-
const clientAuthentication = mockClientAuthentication();
|
|
512
|
-
clientAuthentication.handleIncomingRedirect = jest.fn();
|
|
513
|
-
const mySession = new Session({ clientAuthentication });
|
|
514
|
-
await mySession.handleIncomingRedirect({
|
|
515
|
-
url: "https://some.url",
|
|
516
|
-
});
|
|
517
|
-
expect(mySession.info.isLoggedIn).toBe(false);
|
|
518
|
-
expect(mySession.info.webId).toBeUndefined();
|
|
519
|
-
expect(
|
|
520
|
-
clientAuthentication.handleIncomingRedirect
|
|
521
|
-
).toHaveBeenCalledTimes(1);
|
|
522
|
-
expect(
|
|
523
|
-
window.localStorage.getItem("tmp-resource-server-session-enabled")
|
|
524
|
-
).toBe("false");
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
it("does not attempt to use the workaround if it is explicitly disabled", async () => {
|
|
528
|
-
mockLocalStorage({
|
|
529
|
-
"tmp-resource-server-session-info": JSON.stringify({
|
|
530
|
-
webId: "https://my.pod/profile#me",
|
|
531
|
-
sessions: {
|
|
532
|
-
"https://my.pod/": { expiration: 9000000000000 },
|
|
533
|
-
},
|
|
534
|
-
}),
|
|
535
|
-
});
|
|
536
|
-
const clientAuthentication = mockClientAuthentication();
|
|
537
|
-
clientAuthentication.handleIncomingRedirect = jest.fn();
|
|
538
|
-
const mySession = new Session({ clientAuthentication });
|
|
539
|
-
await mySession.handleIncomingRedirect({
|
|
540
|
-
url: "https://some.url",
|
|
541
|
-
useEssSession: false,
|
|
542
|
-
});
|
|
543
|
-
expect(mySession.info.isLoggedIn).toBe(false);
|
|
544
|
-
expect(mySession.info.webId).toBeUndefined();
|
|
545
|
-
expect(
|
|
546
|
-
clientAuthentication.handleIncomingRedirect
|
|
547
|
-
).toHaveBeenCalledTimes(1);
|
|
548
|
-
expect(
|
|
549
|
-
window.localStorage.getItem("tmp-resource-server-session-enabled")
|
|
550
|
-
).toBe("false");
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
it("does not mark an almost-expired session as logged in", async () => {
|
|
554
|
-
mockLocalStorage({
|
|
555
|
-
"tmp-resource-server-session-info": JSON.stringify({
|
|
556
|
-
webId: "https://my.pod/profile#me",
|
|
557
|
-
sessions: {
|
|
558
|
-
"https://my.pod/": { expiration: Date.now() + 10000 },
|
|
559
|
-
},
|
|
560
|
-
}),
|
|
561
|
-
});
|
|
562
|
-
|
|
563
|
-
const clientAuthentication = mockClientAuthentication();
|
|
564
|
-
clientAuthentication.handleIncomingRedirect = jest.fn();
|
|
565
|
-
const mySession = new Session({ clientAuthentication });
|
|
566
|
-
await mySession.handleIncomingRedirect({
|
|
567
|
-
url: "https://some.url",
|
|
568
|
-
useEssSession: true,
|
|
569
|
-
});
|
|
570
|
-
expect(mySession.info.isLoggedIn).toBe(false);
|
|
571
|
-
expect(mySession.info.webId).toBeUndefined();
|
|
572
|
-
expect(
|
|
573
|
-
clientAuthentication.handleIncomingRedirect
|
|
574
|
-
).toHaveBeenCalledTimes(1);
|
|
575
|
-
});
|
|
576
|
-
|
|
577
|
-
it("logs you in even if your Solid Identity Provider is not your Resource server", async () => {
|
|
578
|
-
mockLocalStorage({
|
|
579
|
-
"tmp-resource-server-session-info": JSON.stringify({
|
|
580
|
-
webId: "https://my.pod/profile#me",
|
|
581
|
-
sessions: {
|
|
582
|
-
"https://not.my.pod/": { expiration: 9000000000000 },
|
|
583
|
-
},
|
|
584
|
-
}),
|
|
585
|
-
});
|
|
586
|
-
const clientAuthentication = mockClientAuthentication();
|
|
587
|
-
clientAuthentication.handleIncomingRedirect = jest.fn();
|
|
588
|
-
const mySession = new Session({ clientAuthentication });
|
|
589
|
-
await mySession.handleIncomingRedirect({
|
|
590
|
-
url: "https://some.url",
|
|
591
|
-
useEssSession: true,
|
|
592
|
-
});
|
|
593
|
-
expect(mySession.info.isLoggedIn).toBe(true);
|
|
594
|
-
expect(mySession.info.webId).toBe("https://my.pod/profile#me");
|
|
595
|
-
expect(
|
|
596
|
-
clientAuthentication.handleIncomingRedirect
|
|
597
|
-
).toHaveBeenCalledTimes(0);
|
|
598
|
-
});
|
|
599
|
-
|
|
600
|
-
it("does not log the user in if the data in the storage was invalid", async () => {
|
|
601
|
-
mockLocalStorage({
|
|
602
|
-
"tmp-resource-server-session-info": JSON.stringify({
|
|
603
|
-
webId: "https://my.pod/profile#me",
|
|
604
|
-
// `sessions` key is intentionally missing
|
|
605
|
-
}),
|
|
606
|
-
});
|
|
607
|
-
const clientAuthentication = mockClientAuthentication();
|
|
608
|
-
clientAuthentication.handleIncomingRedirect = jest.fn();
|
|
609
|
-
const mySession = new Session({ clientAuthentication });
|
|
610
|
-
await mySession.handleIncomingRedirect({
|
|
611
|
-
url: "https://some.url",
|
|
612
|
-
useEssSession: true,
|
|
613
|
-
});
|
|
614
|
-
expect(mySession.info.isLoggedIn).toBe(false);
|
|
615
|
-
expect(mySession.info.webId).toBeUndefined();
|
|
616
|
-
expect(
|
|
617
|
-
clientAuthentication.handleIncomingRedirect
|
|
618
|
-
).toHaveBeenCalledTimes(1);
|
|
619
|
-
});
|
|
620
|
-
});
|
|
621
|
-
|
|
622
398
|
it("posts the redirect IRI to the parent if in an iframe", async () => {
|
|
623
399
|
// Pretend we are in an iframe.
|
|
624
400
|
const frameElement = jest.spyOn(window, "frameElement", "get");
|
package/src/Session.ts
CHANGED
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
ILoginInputOptions,
|
|
29
29
|
ISessionInfo,
|
|
30
30
|
IStorage,
|
|
31
|
-
ResourceServerSession,
|
|
32
31
|
} from "@inrupt/solid-client-authn-core";
|
|
33
32
|
import { v4 } from "uuid";
|
|
34
33
|
import ClientAuthentication from "./ClientAuthentication";
|
|
@@ -83,6 +82,8 @@ export interface IHandleIncomingRedirectOptions {
|
|
|
83
82
|
* `useEssSession` defaults to false and will be removed in the future; to
|
|
84
83
|
* preserve sessions across page reloads, use of `restorePreviousSession` is
|
|
85
84
|
* recommended.
|
|
85
|
+
*
|
|
86
|
+
* @deprecated unreleased
|
|
86
87
|
*/
|
|
87
88
|
useEssSession?: boolean;
|
|
88
89
|
/**
|
|
@@ -148,9 +149,6 @@ export class Session extends EventEmitter {
|
|
|
148
149
|
|
|
149
150
|
private tokenRequestInProgress = false;
|
|
150
151
|
|
|
151
|
-
// Remove this when removing the `useEssSession` workaround:
|
|
152
|
-
private tmpFetchWithCookies = false;
|
|
153
|
-
|
|
154
152
|
/**
|
|
155
153
|
* Session object constructor. Typically called as follows:
|
|
156
154
|
*
|
|
@@ -237,6 +235,11 @@ export class Session extends EventEmitter {
|
|
|
237
235
|
this.on(EVENTS.SESSION_EXPIRED, () => this.internalLogout(false));
|
|
238
236
|
|
|
239
237
|
this.on(EVENTS.ERROR, () => this.internalLogout(false));
|
|
238
|
+
|
|
239
|
+
// @deprecated: Remove this when removing all support for the useEssSession parameter.
|
|
240
|
+
// This intends at cleaning up local storage of applications from data related
|
|
241
|
+
// to the resource server session workaround.
|
|
242
|
+
window.localStorage.removeItem("tmp-resource-server-session-enabled");
|
|
240
243
|
}
|
|
241
244
|
|
|
242
245
|
/**
|
|
@@ -271,14 +274,7 @@ export class Session extends EventEmitter {
|
|
|
271
274
|
* @param init Optional parameters customizing the request, by specifying an HTTP method, headers, a body, etc. Follows the [WHATWG Fetch Standard](https://fetch.spec.whatwg.org/).
|
|
272
275
|
*/
|
|
273
276
|
fetch = async (url: RequestInfo, init?: RequestInit): Promise<Response> => {
|
|
274
|
-
return this.clientAuthentication.fetch(url,
|
|
275
|
-
...init,
|
|
276
|
-
credentials: this.tmpFetchWithCookies
|
|
277
|
-
? /* istanbul ignore next Simulating a cookie-enabled session in tests is too much work for a temporary, disabled-by-default workaround: */
|
|
278
|
-
"include"
|
|
279
|
-
: /* istanbul ignore next Simulating a cookie-enabled session in tests is too much work for a temporary, disabled-by-default workaround: */
|
|
280
|
-
init?.credentials,
|
|
281
|
-
});
|
|
277
|
+
return this.clientAuthentication.fetch(url, init);
|
|
282
278
|
};
|
|
283
279
|
|
|
284
280
|
/**
|
|
@@ -295,7 +291,6 @@ export class Session extends EventEmitter {
|
|
|
295
291
|
window.localStorage.removeItem(KEY_CURRENT_SESSION);
|
|
296
292
|
await this.clientAuthentication.logout(this.info.sessionId);
|
|
297
293
|
this.info.isLoggedIn = false;
|
|
298
|
-
this.tmpFetchWithCookies = false;
|
|
299
294
|
if (emitSignal) {
|
|
300
295
|
this.emit(EVENTS.LOGOUT);
|
|
301
296
|
}
|
|
@@ -333,81 +328,6 @@ export class Session extends EventEmitter {
|
|
|
333
328
|
return undefined;
|
|
334
329
|
}
|
|
335
330
|
|
|
336
|
-
// Unfortunately, regular sessions are lost when the user refreshes the page or opens a new tab.
|
|
337
|
-
// While we're figuring out the API for a longer-term solution, as a temporary workaround some
|
|
338
|
-
// *resource* servers set a cookie that keeps the user logged in after authenticated requests,
|
|
339
|
-
// and expose the fact that they set it on a special endpoint.
|
|
340
|
-
// After login, we store that fact in LocalStorage. This means that we can now look for that
|
|
341
|
-
// data, and if present, indicate that the user is already logged in.
|
|
342
|
-
// Note that there are a lot of edge cases that won't work well with this approach, so it willl
|
|
343
|
-
// be removed in due time, and is disabled by default.
|
|
344
|
-
if (
|
|
345
|
-
options.useEssSession !== true ||
|
|
346
|
-
options.restorePreviousSession === true
|
|
347
|
-
) {
|
|
348
|
-
window.localStorage.setItem(
|
|
349
|
-
"tmp-resource-server-session-enabled",
|
|
350
|
-
"false"
|
|
351
|
-
);
|
|
352
|
-
} else {
|
|
353
|
-
window.localStorage.setItem(
|
|
354
|
-
"tmp-resource-server-session-enabled",
|
|
355
|
-
"true"
|
|
356
|
-
);
|
|
357
|
-
}
|
|
358
|
-
const storedSessionCookieReference = window.localStorage.getItem(
|
|
359
|
-
"tmp-resource-server-session-info"
|
|
360
|
-
);
|
|
361
|
-
if (
|
|
362
|
-
typeof storedSessionCookieReference === "string" &&
|
|
363
|
-
options.restorePreviousSession !== true &&
|
|
364
|
-
options.useEssSession === true
|
|
365
|
-
) {
|
|
366
|
-
// TOOD: Re-use the type used when writing this data:
|
|
367
|
-
// https://github.com/inrupt/solid-client-authn-js/pull/920/files#diff-659ac87dfd3711f4cfcea3c7bf6970980f4740fd59df45f04c7977bffaa23e98R118
|
|
368
|
-
// To keep temporary code together
|
|
369
|
-
// eslint-disable-next-line no-inner-declarations
|
|
370
|
-
function isValidSessionCookieReference(
|
|
371
|
-
reference: Record<string, unknown>
|
|
372
|
-
): reference is ResourceServerSession {
|
|
373
|
-
const resourceServers = Object.keys(
|
|
374
|
-
(reference as ResourceServerSession).sessions ?? {}
|
|
375
|
-
);
|
|
376
|
-
return (
|
|
377
|
-
typeof (reference as ResourceServerSession).webId === "string" &&
|
|
378
|
-
resourceServers.length > 0 &&
|
|
379
|
-
typeof (reference as ResourceServerSession).sessions[
|
|
380
|
-
resourceServers[0]
|
|
381
|
-
].expiration === "number"
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
const reference = JSON.parse(storedSessionCookieReference);
|
|
385
|
-
if (isValidSessionCookieReference(reference)) {
|
|
386
|
-
const resourceServers = Object.keys(reference.sessions);
|
|
387
|
-
const webIdOrigin = new URL(reference.webId).hostname;
|
|
388
|
-
const ownResourceServer = resourceServers.find((resourceServer) => {
|
|
389
|
-
return new URL(resourceServer).hostname === webIdOrigin;
|
|
390
|
-
});
|
|
391
|
-
// Usually the user's WebID is also a Resource server for them,
|
|
392
|
-
// so we pick the expiration time for that. If it doesn't exist,
|
|
393
|
-
// we just pick the first (and probably only) one:
|
|
394
|
-
const relevantServer = ownResourceServer ?? resourceServers[0];
|
|
395
|
-
// If the cookie is valid for fewer than five minutes,
|
|
396
|
-
// pretend it's not valid anymore already, to avoid small misalignments
|
|
397
|
-
// resulting in invalid states:
|
|
398
|
-
if (
|
|
399
|
-
reference.sessions[relevantServer].expiration - Date.now() >
|
|
400
|
-
5 * 60 * 1000
|
|
401
|
-
) {
|
|
402
|
-
this.info.isLoggedIn = true;
|
|
403
|
-
this.info.webId = reference.webId;
|
|
404
|
-
this.tmpFetchWithCookies = true;
|
|
405
|
-
return this.info;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
// end of temporary workaround.
|
|
410
|
-
|
|
411
331
|
this.tokenRequestInProgress = true;
|
|
412
332
|
const sessionInfo = await this.clientAuthentication.handleIncomingRedirect(
|
|
413
333
|
url,
|
|
@@ -25,12 +25,12 @@ import {
|
|
|
25
25
|
} from "@inrupt/solid-client-authn-core";
|
|
26
26
|
import { jest } from "@jest/globals";
|
|
27
27
|
|
|
28
|
-
export const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
28
|
+
export const mockedRedirect = jest.fn<
|
|
29
|
+
void,
|
|
30
|
+
[redirectUrl: string, redirectOptions: IRedirectorOptions]
|
|
31
|
+
>();
|
|
32
|
+
export const mockRedirector = (): IRedirector => {
|
|
33
|
+
return {
|
|
34
|
+
redirect: mockedRedirect,
|
|
35
|
+
};
|
|
36
|
+
};
|