@inrupt/solid-client-authn-browser 1.13.4 → 1.15.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/ClientAuthentication.d.ts +1 -1
- package/dist/ClientAuthentication.js +2 -1
- package/dist/ClientAuthentication.js.map +1 -1
- package/dist/Session.d.ts +5 -3
- package/dist/Session.js +21 -17
- package/dist/Session.js.map +1 -1
- package/dist/defaultSession.d.ts +1 -0
- package/dist/defaultSession.js +5 -1
- package/dist/defaultSession.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/login/oidc/IssuerConfigFetcher.js +2 -1
- package/dist/login/oidc/IssuerConfigFetcher.js.map +1 -1
- package/dist/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.d.ts +1 -0
- package/dist/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.js +2 -1
- package/dist/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.js.map +1 -1
- package/dist/sessionInfo/SessionInfoManager.d.ts +1 -0
- package/dist/sessionInfo/SessionInfoManager.js +2 -1
- package/dist/sessionInfo/SessionInfoManager.js.map +1 -1
- package/dist/solid-client-authn.bundle.js +1 -1
- package/package.json +5 -7
- package/src/ClientAuthentication.spec.ts +15 -8
- package/src/ClientAuthentication.ts +2 -2
- package/src/Session.spec.ts +255 -119
- package/src/Session.ts +44 -18
- package/src/defaultSession.spec.ts +28 -19
- package/src/defaultSession.ts +15 -1
- package/src/index.ts +1 -0
- package/src/login/oidc/ClientRegistrar.spec.ts +1 -1
- package/src/login/oidc/IssuerConfigFetcher.spec.ts +60 -40
- package/src/login/oidc/IssuerConfigFetcher.ts +2 -1
- package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.spec.ts +27 -22
- package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.ts +2 -0
- package/src/login/oidc/incomingRedirectHandler/ErrorOidcHandler.spec.ts +12 -3
- package/src/login/oidc/incomingRedirectHandler/FallbackRedirectHandler.spec.ts +12 -1
- package/src/sessionInfo/SessionInfoManager.ts +1 -0
- package/tsconfig.json +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inrupt/solid-client-authn-browser",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"types": "dist/index",
|
|
6
6
|
"browser": "dist/index.js",
|
|
@@ -25,8 +25,9 @@
|
|
|
25
25
|
"cross-fetch": "^3.1.5"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@inrupt/oidc-client-ext": "^1.
|
|
29
|
-
"@inrupt/solid-client-authn-core": "^1.
|
|
28
|
+
"@inrupt/oidc-client-ext": "^1.15.0",
|
|
29
|
+
"@inrupt/solid-client-authn-core": "^1.15.0",
|
|
30
|
+
"@inrupt/universal-fetch": "^1.0.1",
|
|
30
31
|
"@types/lodash.clonedeep": "^4.5.6",
|
|
31
32
|
"@types/node": "^18.0.3",
|
|
32
33
|
"@types/uuid": "^9.0.1",
|
|
@@ -38,8 +39,5 @@
|
|
|
38
39
|
"publishConfig": {
|
|
39
40
|
"access": "public"
|
|
40
41
|
},
|
|
41
|
-
"
|
|
42
|
-
"node": "^14.0.0 || ^16.0.0"
|
|
43
|
-
},
|
|
44
|
-
"gitHead": "ab437bbfb613f4f64b82b17e3a38177998a1762a"
|
|
42
|
+
"gitHead": "e8f87a62bf739970d3fb5bc3fb48e587871f3719"
|
|
45
43
|
}
|
|
@@ -36,6 +36,9 @@ import {
|
|
|
36
36
|
mockHandleIncomingRedirect,
|
|
37
37
|
} from "@inrupt/solid-client-authn-core/mocks";
|
|
38
38
|
|
|
39
|
+
import { fetch } from "@inrupt/universal-fetch";
|
|
40
|
+
import * as UniversalFetch from "@inrupt/universal-fetch";
|
|
41
|
+
|
|
39
42
|
import { mockLoginHandler } from "./login/__mocks__/LoginHandler";
|
|
40
43
|
import { mockLogoutHandler } from "./logout/__mocks__/LogoutHandler";
|
|
41
44
|
import {
|
|
@@ -45,6 +48,16 @@ import {
|
|
|
45
48
|
import ClientAuthentication from "./ClientAuthentication";
|
|
46
49
|
import { mockDefaultIssuerConfigFetcher } from "./login/oidc/__mocks__/IssuerConfigFetcher";
|
|
47
50
|
|
|
51
|
+
jest.mock("@inrupt/universal-fetch", () => {
|
|
52
|
+
const fetchModule = jest.requireActual(
|
|
53
|
+
"@inrupt/universal-fetch"
|
|
54
|
+
) as typeof UniversalFetch;
|
|
55
|
+
return {
|
|
56
|
+
...fetchModule,
|
|
57
|
+
fetch: jest.fn<typeof fetch>(),
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
|
|
48
61
|
jest.mock("@inrupt/solid-client-authn-core", () => {
|
|
49
62
|
const actualCoreModule = jest.requireActual(
|
|
50
63
|
"@inrupt/solid-client-authn-core"
|
|
@@ -284,13 +297,9 @@ describe("ClientAuthentication", () => {
|
|
|
284
297
|
|
|
285
298
|
describe("fetch", () => {
|
|
286
299
|
it("calls fetch", async () => {
|
|
287
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
288
300
|
const clientAuthn = getClientAuthentication();
|
|
289
301
|
await clientAuthn.fetch("https://html5zombo.com");
|
|
290
|
-
expect(
|
|
291
|
-
"https://html5zombo.com",
|
|
292
|
-
undefined
|
|
293
|
-
);
|
|
302
|
+
expect(fetch).toHaveBeenCalledWith("https://html5zombo.com", undefined);
|
|
294
303
|
});
|
|
295
304
|
});
|
|
296
305
|
|
|
@@ -299,7 +308,6 @@ describe("ClientAuthentication", () => {
|
|
|
299
308
|
// TODO: add tests for events & errors
|
|
300
309
|
|
|
301
310
|
it("reverts back to un-authenticated fetch on logout", async () => {
|
|
302
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
303
311
|
// eslint-disable-next-line no-restricted-globals
|
|
304
312
|
history.replaceState = jest.fn();
|
|
305
313
|
const clientAuthn = getClientAuthentication();
|
|
@@ -314,13 +322,12 @@ describe("ClientAuthentication", () => {
|
|
|
314
322
|
expect(clientAuthn.fetch).not.toBe(unauthFetch);
|
|
315
323
|
|
|
316
324
|
await clientAuthn.logout("mySession");
|
|
317
|
-
const spyFetch = jest.spyOn(window, "fetch");
|
|
318
325
|
await clientAuthn.fetch("https://example.com", {
|
|
319
326
|
credentials: "omit",
|
|
320
327
|
});
|
|
321
328
|
// Calling logout should revert back to our un-authenticated fetch.
|
|
322
329
|
expect(clientAuthn.fetch).toBe(unauthFetch);
|
|
323
|
-
expect(
|
|
330
|
+
expect(fetch).toHaveBeenCalledWith("https://example.com", {
|
|
324
331
|
credentials: "omit",
|
|
325
332
|
});
|
|
326
333
|
});
|
|
@@ -36,14 +36,14 @@ import {
|
|
|
36
36
|
EVENTS,
|
|
37
37
|
isValidRedirectUrl,
|
|
38
38
|
} from "@inrupt/solid-client-authn-core";
|
|
39
|
+
import { fetch } from "@inrupt/universal-fetch";
|
|
39
40
|
import { removeOidcQueryParam } from "@inrupt/oidc-client-ext";
|
|
40
41
|
import { EventEmitter } from "events";
|
|
41
42
|
|
|
42
43
|
// By only referring to `window` at runtime, apps that do server-side rendering
|
|
43
44
|
// won't run into errors when rendering code that instantiates a
|
|
44
45
|
// ClientAuthentication:
|
|
45
|
-
const globalFetch: typeof
|
|
46
|
-
window.fetch(request, init);
|
|
46
|
+
const globalFetch: typeof fetch = (request, init) => fetch(request, init);
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* @hidden
|
package/src/Session.spec.ts
CHANGED
|
@@ -27,15 +27,27 @@ import {
|
|
|
27
27
|
USER_SESSION_PREFIX,
|
|
28
28
|
} from "@inrupt/solid-client-authn-core";
|
|
29
29
|
import { mockStorage } from "@inrupt/solid-client-authn-core/mocks";
|
|
30
|
+
import { fetch } from "@inrupt/universal-fetch";
|
|
31
|
+
import * as UniversalFetch from "@inrupt/universal-fetch";
|
|
30
32
|
import { mockClientAuthentication } from "./__mocks__/ClientAuthentication";
|
|
31
33
|
import { Session } from "./Session";
|
|
32
34
|
import { LocalStorageMock } from "./storage/__mocks__/LocalStorage";
|
|
33
35
|
import { mockSessionInfoManager } from "./sessionInfo/__mocks__/SessionInfoManager";
|
|
34
36
|
import { KEY_CURRENT_SESSION, KEY_CURRENT_URL } from "./constant";
|
|
35
|
-
import
|
|
37
|
+
import ClientAuthentication from "./ClientAuthentication";
|
|
36
38
|
|
|
37
39
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
38
40
|
|
|
41
|
+
jest.mock("@inrupt/universal-fetch", () => {
|
|
42
|
+
const fetchModule = jest.requireActual(
|
|
43
|
+
"@inrupt/universal-fetch"
|
|
44
|
+
) as typeof UniversalFetch;
|
|
45
|
+
return {
|
|
46
|
+
...fetchModule,
|
|
47
|
+
fetch: jest.fn<typeof fetch>(),
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
|
|
39
51
|
const mockLocalStorage = (stored: Record<string, string>) => {
|
|
40
52
|
Object.defineProperty(window, "localStorage", {
|
|
41
53
|
value: new LocalStorageMock(stored),
|
|
@@ -202,7 +214,6 @@ describe("Session", () => {
|
|
|
202
214
|
|
|
203
215
|
describe("fetch", () => {
|
|
204
216
|
it("wraps up ClientAuthentication fetch if logged in", async () => {
|
|
205
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
206
217
|
const clientAuthentication = mockClientAuthentication();
|
|
207
218
|
const clientAuthnFetch = jest.spyOn(clientAuthentication, "fetch");
|
|
208
219
|
const mySession = new Session({ clientAuthentication });
|
|
@@ -212,7 +223,6 @@ describe("Session", () => {
|
|
|
212
223
|
});
|
|
213
224
|
|
|
214
225
|
it("preserves a binding to its Session instance", async () => {
|
|
215
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
216
226
|
const clientAuthentication = mockClientAuthentication();
|
|
217
227
|
const clientAuthnFetch = jest.spyOn(clientAuthentication, "fetch");
|
|
218
228
|
const mySession = new Session({ clientAuthentication });
|
|
@@ -225,12 +235,10 @@ describe("Session", () => {
|
|
|
225
235
|
});
|
|
226
236
|
|
|
227
237
|
it("does not rebind window.fetch if logged out", async () => {
|
|
228
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
229
238
|
const clientAuthentication = mockClientAuthentication();
|
|
230
239
|
const mySession = new Session({ clientAuthentication });
|
|
231
240
|
await mySession.fetch("https://some.url/");
|
|
232
|
-
expect(
|
|
233
|
-
expect((window.fetch as jest.Mock).mock.instances).toEqual([window]);
|
|
241
|
+
expect(fetch).toHaveBeenCalled();
|
|
234
242
|
});
|
|
235
243
|
});
|
|
236
244
|
|
|
@@ -408,19 +416,6 @@ describe("Session", () => {
|
|
|
408
416
|
});
|
|
409
417
|
});
|
|
410
418
|
|
|
411
|
-
describe("onError", () => {
|
|
412
|
-
it("calls the registered callback on error", async () => {
|
|
413
|
-
const onErrorCallback = jest.fn();
|
|
414
|
-
const mySession = new Session();
|
|
415
|
-
mySession.onError(onErrorCallback);
|
|
416
|
-
mySession.emit(EVENTS.ERROR, "error", "error_description");
|
|
417
|
-
expect(onErrorCallback).toHaveBeenCalledWith(
|
|
418
|
-
"error",
|
|
419
|
-
"error_description"
|
|
420
|
-
);
|
|
421
|
-
});
|
|
422
|
-
});
|
|
423
|
-
|
|
424
419
|
describe("silent authentication", () => {
|
|
425
420
|
it("does nothing if no previous session is available", async () => {
|
|
426
421
|
mockLocalStorage({});
|
|
@@ -777,130 +772,271 @@ describe("Session", () => {
|
|
|
777
772
|
});
|
|
778
773
|
});
|
|
779
774
|
|
|
780
|
-
describe("
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
775
|
+
describe("legacy events handlers", () => {
|
|
776
|
+
describe("onError", () => {
|
|
777
|
+
it("calls the registered callback on error", async () => {
|
|
778
|
+
const onErrorCallback = jest.fn();
|
|
779
|
+
const mySession = new Session();
|
|
780
|
+
mySession.onError(onErrorCallback);
|
|
781
|
+
mySession.emit(EVENTS.ERROR, "error", "error_description");
|
|
782
|
+
expect(onErrorCallback).toHaveBeenCalledWith(
|
|
783
|
+
"error",
|
|
784
|
+
"error_description"
|
|
785
|
+
);
|
|
790
786
|
});
|
|
791
|
-
mockLocalStorage({});
|
|
792
|
-
const mySession = new Session({ clientAuthentication });
|
|
793
|
-
mySession.onLogin(myCallback);
|
|
794
|
-
await mySession.handleIncomingRedirect("https://some.url");
|
|
795
|
-
expect(myCallback).toHaveBeenCalled();
|
|
796
787
|
});
|
|
797
788
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
789
|
+
describe("onLogin", () => {
|
|
790
|
+
it("calls the registered callback on login", async () => {
|
|
791
|
+
const myCallback = jest.fn();
|
|
792
|
+
const clientAuthentication = mockClientAuthentication();
|
|
793
|
+
clientAuthentication.handleIncomingRedirect = (
|
|
794
|
+
jest.fn() as any
|
|
795
|
+
).mockResolvedValue({
|
|
796
|
+
isLoggedIn: true,
|
|
797
|
+
sessionId: "a session ID",
|
|
798
|
+
webId: "https://some.webid#them",
|
|
799
|
+
});
|
|
800
|
+
mockLocalStorage({});
|
|
801
|
+
const mySession = new Session({ clientAuthentication });
|
|
802
|
+
mySession.onLogin(myCallback);
|
|
803
|
+
await mySession.handleIncomingRedirect("https://some.url");
|
|
804
|
+
expect(myCallback).toHaveBeenCalled();
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
it("does not call the registered callback if login isn't successful", async () => {
|
|
808
|
+
const failCallback = (): void => {
|
|
809
|
+
throw new Error(
|
|
810
|
+
"Should *NOT* call callback - this means test has failed!"
|
|
811
|
+
);
|
|
812
|
+
};
|
|
813
|
+
const clientAuthentication = mockClientAuthentication();
|
|
814
|
+
clientAuthentication.handleIncomingRedirect = jest.fn(
|
|
815
|
+
async (_url: string) => {
|
|
816
|
+
return {
|
|
817
|
+
isLoggedIn: false,
|
|
818
|
+
sessionId: "a session ID",
|
|
819
|
+
webId: "https://some.webid#them",
|
|
820
|
+
};
|
|
821
|
+
}
|
|
802
822
|
);
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
823
|
+
const mySession = new Session({ clientAuthentication });
|
|
824
|
+
mySession.onLogin(failCallback);
|
|
825
|
+
await expect(
|
|
826
|
+
mySession.handleIncomingRedirect("https://some.url")
|
|
827
|
+
).resolves.not.toThrow();
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
it("sets the appropriate information before calling the callback", async () => {
|
|
831
|
+
const clientAuthentication = mockClientAuthentication();
|
|
832
|
+
clientAuthentication.handleIncomingRedirect = jest.fn(
|
|
833
|
+
async (_url: string) => {
|
|
834
|
+
return {
|
|
835
|
+
isLoggedIn: true,
|
|
836
|
+
sessionId: "a session ID",
|
|
837
|
+
webId: "https://some.webid#them",
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
);
|
|
841
|
+
const mySession = new Session({ clientAuthentication });
|
|
842
|
+
const myCallback = jest.fn((): void => {
|
|
843
|
+
expect(mySession.info.webId).toBe("https://some.webid#them");
|
|
844
|
+
});
|
|
845
|
+
mySession.onLogin(myCallback);
|
|
846
|
+
await mySession.handleIncomingRedirect("https://some.url");
|
|
847
|
+
expect(myCallback).toHaveBeenCalled();
|
|
848
|
+
// Verify that the conditional assertion has been called
|
|
849
|
+
expect.assertions(2);
|
|
850
|
+
});
|
|
819
851
|
});
|
|
820
852
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
);
|
|
832
|
-
const mySession = new Session({ clientAuthentication });
|
|
833
|
-
const myCallback = jest.fn((): void => {
|
|
834
|
-
expect(mySession.info.webId).toBe("https://some.webid#them");
|
|
853
|
+
describe("onLogout", () => {
|
|
854
|
+
it("calls the registered callback on logout", async () => {
|
|
855
|
+
const myCallback = jest.fn();
|
|
856
|
+
const mySession = new Session({
|
|
857
|
+
clientAuthentication: mockClientAuthentication(),
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
mySession.onLogout(myCallback);
|
|
861
|
+
await mySession.logout();
|
|
862
|
+
expect(myCallback).toHaveBeenCalled();
|
|
835
863
|
});
|
|
836
|
-
mySession.onLogin(myCallback);
|
|
837
|
-
await mySession.handleIncomingRedirect("https://some.url");
|
|
838
|
-
expect(myCallback).toHaveBeenCalled();
|
|
839
|
-
// Verify that the conditional assertion has been called
|
|
840
|
-
expect.assertions(2);
|
|
841
864
|
});
|
|
842
|
-
});
|
|
843
865
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
866
|
+
describe("onSessionRestore", () => {
|
|
867
|
+
it("calls the registered callback on session restore", async () => {
|
|
868
|
+
// Set our window's location to our test value.
|
|
869
|
+
const defaultLocation = "https://coolSite.com/resource";
|
|
870
|
+
const currentLocation = "https://coolSite.com/redirect";
|
|
871
|
+
|
|
872
|
+
// This pretends we have previously triggered silent authentication and stored
|
|
873
|
+
// the location.
|
|
874
|
+
mockLocalStorage({
|
|
875
|
+
[KEY_CURRENT_URL]: defaultLocation,
|
|
876
|
+
});
|
|
877
|
+
// This acts as the URL the user has been redirected to.
|
|
878
|
+
mockLocation(currentLocation);
|
|
879
|
+
// This pretends the login is successful.
|
|
880
|
+
const clientAuthentication = mockClientAuthentication();
|
|
881
|
+
clientAuthentication.handleIncomingRedirect = (
|
|
882
|
+
jest.fn() as any
|
|
883
|
+
).mockResolvedValue({
|
|
884
|
+
isLoggedIn: true,
|
|
885
|
+
sessionId: "a session ID",
|
|
886
|
+
webId: "https://some.webid#them",
|
|
887
|
+
});
|
|
888
|
+
|
|
889
|
+
const mySession = new Session({
|
|
890
|
+
clientAuthentication,
|
|
891
|
+
});
|
|
892
|
+
const myCallback = (urlBeforeRestore: string): void => {
|
|
893
|
+
expect(urlBeforeRestore).toEqual(defaultLocation);
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
mySession.onSessionRestore(myCallback);
|
|
897
|
+
await mySession.handleIncomingRedirect(currentLocation);
|
|
898
|
+
|
|
899
|
+
// This verifies that the callback has been called
|
|
900
|
+
expect.assertions(1);
|
|
849
901
|
});
|
|
902
|
+
});
|
|
850
903
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
904
|
+
describe("onSessionExpiration", () => {
|
|
905
|
+
it("calls the provided callback when receiving the appropriate event", async () => {
|
|
906
|
+
const myCallback = jest.fn();
|
|
907
|
+
const mySession = new Session({
|
|
908
|
+
clientAuthentication: mockClientAuthentication(),
|
|
909
|
+
});
|
|
910
|
+
mySession.onSessionExpiration(myCallback);
|
|
911
|
+
mySession.emit(EVENTS.SESSION_EXPIRED);
|
|
912
|
+
expect(myCallback).toHaveBeenCalled();
|
|
913
|
+
});
|
|
854
914
|
});
|
|
855
915
|
});
|
|
856
916
|
|
|
857
|
-
describe("
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
917
|
+
describe("events.on", () => {
|
|
918
|
+
describe("login", () => {
|
|
919
|
+
it("calls the registered callback on login", async () => {
|
|
920
|
+
const myCallback = jest.fn();
|
|
921
|
+
const clientAuthentication = mockClientAuthentication();
|
|
922
|
+
clientAuthentication.handleIncomingRedirect = jest
|
|
923
|
+
.fn<ClientAuthentication["handleIncomingRedirect"]>()
|
|
924
|
+
.mockResolvedValue({
|
|
925
|
+
isLoggedIn: true,
|
|
926
|
+
sessionId: "a session ID",
|
|
927
|
+
webId: "https://some.webid#them",
|
|
928
|
+
});
|
|
929
|
+
mockLocalStorage({});
|
|
930
|
+
const mySession = new Session({ clientAuthentication });
|
|
931
|
+
mySession.events.on(EVENTS.LOGIN, myCallback);
|
|
932
|
+
await mySession.handleIncomingRedirect("https://some.url");
|
|
933
|
+
expect(myCallback).toHaveBeenCalled();
|
|
934
|
+
});
|
|
862
935
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
936
|
+
it("does not call the registered callback if login isn't successful", async () => {
|
|
937
|
+
const myCallback = jest.fn();
|
|
938
|
+
const clientAuthentication = mockClientAuthentication();
|
|
939
|
+
clientAuthentication.handleIncomingRedirect = jest
|
|
940
|
+
.fn<ClientAuthentication["handleIncomingRedirect"]>()
|
|
941
|
+
.mockResolvedValue({
|
|
942
|
+
isLoggedIn: true,
|
|
943
|
+
sessionId: "a session ID",
|
|
944
|
+
webId: "https://some.webid#them",
|
|
945
|
+
});
|
|
946
|
+
const mySession = new Session({ clientAuthentication });
|
|
947
|
+
mySession.events.on(EVENTS.LOGIN, myCallback);
|
|
948
|
+
expect(myCallback).not.toHaveBeenCalled();
|
|
867
949
|
});
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
950
|
+
|
|
951
|
+
it("sets the appropriate information before calling the callback", async () => {
|
|
952
|
+
const clientAuthentication = mockClientAuthentication();
|
|
953
|
+
clientAuthentication.handleIncomingRedirect = jest
|
|
954
|
+
.fn<ClientAuthentication["handleIncomingRedirect"]>()
|
|
955
|
+
.mockResolvedValue({
|
|
956
|
+
isLoggedIn: true,
|
|
957
|
+
sessionId: "a session ID",
|
|
958
|
+
webId: "https://some.webid#them",
|
|
959
|
+
});
|
|
960
|
+
const mySession = new Session({ clientAuthentication });
|
|
961
|
+
const myCallback = jest.fn((): void => {
|
|
962
|
+
expect(mySession.info.webId).toBe("https://some.webid#them");
|
|
963
|
+
});
|
|
964
|
+
mySession.events.on(EVENTS.LOGIN, myCallback);
|
|
965
|
+
await mySession.handleIncomingRedirect("https://some.url");
|
|
966
|
+
expect(myCallback).toHaveBeenCalled();
|
|
967
|
+
// Verify that the conditional assertion has been called
|
|
968
|
+
expect.assertions(2);
|
|
878
969
|
});
|
|
970
|
+
});
|
|
879
971
|
|
|
880
|
-
|
|
881
|
-
|
|
972
|
+
describe("logout", () => {
|
|
973
|
+
it("calls the registered callback on logout", async () => {
|
|
974
|
+
const myCallback = jest.fn();
|
|
975
|
+
const mySession = new Session({
|
|
976
|
+
clientAuthentication: mockClientAuthentication(),
|
|
977
|
+
});
|
|
978
|
+
|
|
979
|
+
mySession.events.on(EVENTS.LOGOUT, myCallback);
|
|
980
|
+
await mySession.logout();
|
|
981
|
+
expect(myCallback).toHaveBeenCalled();
|
|
882
982
|
});
|
|
883
|
-
|
|
884
|
-
expect(urlBeforeRestore).toEqual(defaultLocation);
|
|
885
|
-
};
|
|
983
|
+
});
|
|
886
984
|
|
|
887
|
-
|
|
888
|
-
|
|
985
|
+
describe("sessionRestore", () => {
|
|
986
|
+
it("calls the registered callback on session restore", async () => {
|
|
987
|
+
// Set our window's location to our test value.
|
|
988
|
+
const defaultLocation = "https://coolSite.com/resource";
|
|
989
|
+
const currentLocation = "https://coolSite.com/redirect";
|
|
889
990
|
|
|
890
|
-
|
|
891
|
-
|
|
991
|
+
// This pretends we have previously triggered silent authentication and stored
|
|
992
|
+
// the location.
|
|
993
|
+
mockLocalStorage({
|
|
994
|
+
[KEY_CURRENT_URL]: defaultLocation,
|
|
995
|
+
});
|
|
996
|
+
// This acts as the URL the user has been redirected to.
|
|
997
|
+
mockLocation(currentLocation);
|
|
998
|
+
// This pretends the login is successful.
|
|
999
|
+
const clientAuthentication = mockClientAuthentication();
|
|
1000
|
+
clientAuthentication.handleIncomingRedirect = jest
|
|
1001
|
+
.fn<ClientAuthentication["handleIncomingRedirect"]>()
|
|
1002
|
+
.mockResolvedValue({
|
|
1003
|
+
isLoggedIn: true,
|
|
1004
|
+
sessionId: "a session ID",
|
|
1005
|
+
webId: "https://some.webid#them",
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
const mySession = new Session({
|
|
1009
|
+
clientAuthentication,
|
|
1010
|
+
});
|
|
1011
|
+
const myCallback = (urlBeforeRestore: string): void => {
|
|
1012
|
+
expect(urlBeforeRestore).toEqual(defaultLocation);
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
mySession.events.on(EVENTS.SESSION_RESTORED, myCallback);
|
|
1016
|
+
await mySession.handleIncomingRedirect(currentLocation);
|
|
1017
|
+
|
|
1018
|
+
// This verifies that the callback has been called
|
|
1019
|
+
expect.assertions(1);
|
|
1020
|
+
});
|
|
892
1021
|
});
|
|
893
1022
|
});
|
|
894
1023
|
|
|
895
|
-
describe("
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
mySession.
|
|
902
|
-
|
|
903
|
-
|
|
1024
|
+
describe("proxies events to the session", () => {
|
|
1025
|
+
// This describe block is only required as long as Session extends the EventEmitter
|
|
1026
|
+
// class.
|
|
1027
|
+
it("proxies the EventEmitter calls from events to the session object", () => {
|
|
1028
|
+
const mySession = new Session();
|
|
1029
|
+
const spiedOn = jest.spyOn(mySession, "on");
|
|
1030
|
+
mySession.events.on("login", jest.fn());
|
|
1031
|
+
expect(spiedOn).toHaveBeenCalled();
|
|
1032
|
+
});
|
|
1033
|
+
|
|
1034
|
+
it("throws on calls from events which aren't part of the EventEmitter interface", () => {
|
|
1035
|
+
const mySession = new Session();
|
|
1036
|
+
// @ts-expect-error onLogin is a function on Session, and not SessionEventEmitter
|
|
1037
|
+
expect(() => mySession.events.onLogin(jest.fn())).toThrow(
|
|
1038
|
+
"[onLogin] is not supported"
|
|
1039
|
+
);
|
|
904
1040
|
});
|
|
905
1041
|
});
|
|
906
1042
|
});
|