@inrupt/solid-client-authn-browser 1.13.3 → 1.14.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 +4 -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/incomingRedirectHandler/AuthCodeRedirectHandler.js +0 -6
- package/dist/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.js.map +1 -1
- package/dist/solid-client-authn.bundle.js +1 -1
- package/package.json +4 -4
- package/src/Session.spec.ts +251 -122
- package/src/Session.ts +43 -18
- package/src/defaultSession.spec.ts +28 -19
- package/src/defaultSession.ts +15 -1
- package/src/index.ts +1 -0
- package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.spec.ts +4 -10
- package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.ts +0 -13
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
20
20
|
//
|
|
21
21
|
|
|
22
|
+
import { EVENTS } from "@inrupt/solid-client-authn-core";
|
|
22
23
|
import { jest, it, expect } from "@jest/globals";
|
|
23
24
|
import {
|
|
24
25
|
fetch,
|
|
@@ -29,33 +30,34 @@ import {
|
|
|
29
30
|
onLogin,
|
|
30
31
|
onSessionRestore,
|
|
31
32
|
onLogout,
|
|
33
|
+
events,
|
|
32
34
|
} from "./defaultSession";
|
|
33
|
-
import
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
expect(
|
|
35
|
+
import * as SessionModule from "./Session";
|
|
36
|
+
|
|
37
|
+
it("instantiates the default session lazily", () => {
|
|
38
|
+
const singletonSession = new SessionModule.Session();
|
|
39
|
+
const spiedConstructor = jest
|
|
40
|
+
.spyOn(SessionModule, "Session")
|
|
41
|
+
.mockImplementation(() => singletonSession);
|
|
42
|
+
expect(spiedConstructor).not.toHaveBeenCalled();
|
|
43
|
+
events().on(EVENTS.LOGIN, jest.fn());
|
|
44
|
+
expect(spiedConstructor).toHaveBeenCalled();
|
|
43
45
|
});
|
|
44
46
|
|
|
45
47
|
it("re-uses the same Session when calling multiple methods", () => {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
const singletonSession = new SessionModule.Session();
|
|
49
|
+
const spiedConstructor = jest
|
|
50
|
+
.spyOn(SessionModule, "Session")
|
|
51
|
+
.mockImplementation(() => singletonSession);
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
events().on(EVENTS.LOGIN, jest.fn());
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
expect(spiedConstructor).toHaveBeenCalledTimes(1);
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
events().on(EVENTS.LOGOUT, jest.fn());
|
|
55
58
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
expect(mockedSession.Session).toHaveBeenCalledTimes(1);
|
|
59
|
+
// No new session has been instantiated.
|
|
60
|
+
expect(spiedConstructor).toHaveBeenCalledTimes(1);
|
|
59
61
|
});
|
|
60
62
|
|
|
61
63
|
it("all functions pass on their arguments to the default session", () => {
|
|
@@ -73,6 +75,7 @@ it("all functions pass on their arguments to the default session", () => {
|
|
|
73
75
|
const onLoginSpy = jest.spyOn(defaultSession, "onLogin");
|
|
74
76
|
const onLogoutSpy = jest.spyOn(defaultSession, "onLogout");
|
|
75
77
|
const onSessionRestoreSpy = jest.spyOn(defaultSession, "onSessionRestore");
|
|
78
|
+
const eventsOnSpy = jest.spyOn(defaultSession.events, "on");
|
|
76
79
|
|
|
77
80
|
expect(fetchSpy).not.toHaveBeenCalled();
|
|
78
81
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -94,6 +97,12 @@ it("all functions pass on their arguments to the default session", () => {
|
|
|
94
97
|
handleIncomingRedirect("https://example.com");
|
|
95
98
|
expect(handleIncomingRedirectSpy).toHaveBeenCalledTimes(1);
|
|
96
99
|
|
|
100
|
+
// onLogin will internall call events.on(...), so the following test
|
|
101
|
+
// must come first.
|
|
102
|
+
expect(eventsOnSpy).not.toHaveBeenCalled();
|
|
103
|
+
events().on(EVENTS.LOGIN, jest.fn());
|
|
104
|
+
expect(eventsOnSpy).toHaveBeenCalledTimes(1);
|
|
105
|
+
|
|
97
106
|
expect(onLoginSpy).not.toHaveBeenCalled();
|
|
98
107
|
onLogin(jest.fn());
|
|
99
108
|
expect(onLoginSpy).toHaveBeenCalledTimes(1);
|
package/src/defaultSession.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
import { Session } from "./Session";
|
|
23
23
|
|
|
24
|
-
let defaultSession: Session;
|
|
24
|
+
let defaultSession: Session | undefined;
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Obtain the {@link Session} used when not explicitly instantiating one yourself.
|
|
@@ -97,6 +97,8 @@ export const handleIncomingRedirect: Session["handleIncomingRedirect"] = (
|
|
|
97
97
|
* @since 1.3.0
|
|
98
98
|
*
|
|
99
99
|
* @param callback The function called when a user completes login.
|
|
100
|
+
* @deprecated Prefer events.on(EVENTS.LOGIN, callback)
|
|
101
|
+
|
|
100
102
|
*/
|
|
101
103
|
export const onLogin: Session["onLogin"] = (...args) => {
|
|
102
104
|
const session = getDefaultSession();
|
|
@@ -108,6 +110,8 @@ export const onLogin: Session["onLogin"] = (...args) => {
|
|
|
108
110
|
*
|
|
109
111
|
* @param callback The function called when a user completes logout.
|
|
110
112
|
* @since 1.3.0
|
|
113
|
+
* @deprecated Prefer events.on(EVENTS.LOGOUT, callback)
|
|
114
|
+
|
|
111
115
|
*/
|
|
112
116
|
export const onLogout: Session["onLogout"] = (...args) => {
|
|
113
117
|
const session = getDefaultSession();
|
|
@@ -119,8 +123,18 @@ export const onLogout: Session["onLogout"] = (...args) => {
|
|
|
119
123
|
*
|
|
120
124
|
* @param callback The function called when a session is restored.
|
|
121
125
|
* @since 1.3.0
|
|
126
|
+
* @deprecated Prefer events.on(EVENTS.SESSION_RESTORED, callback)
|
|
122
127
|
*/
|
|
123
128
|
export const onSessionRestore: Session["onSessionRestore"] = (...args) => {
|
|
124
129
|
const session = getDefaultSession();
|
|
125
130
|
return session.onSessionRestore(...args);
|
|
126
131
|
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* {@link SessionEventEmitter} instance to subscribe to events by the default session.
|
|
135
|
+
*
|
|
136
|
+
* @since Unreleased
|
|
137
|
+
*/
|
|
138
|
+
export const events = (): Session["events"] => {
|
|
139
|
+
return getDefaultSession().events;
|
|
140
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -35,7 +35,7 @@ import type * as SolidClientAuthnCore from "@inrupt/solid-client-authn-core";
|
|
|
35
35
|
import { jest, it, describe, expect } from "@jest/globals";
|
|
36
36
|
import { CodeExchangeResult, getBearerToken } from "@inrupt/oidc-client-ext";
|
|
37
37
|
import type * as OidcClientExt from "@inrupt/oidc-client-ext";
|
|
38
|
-
import { Response } from "cross-fetch";
|
|
38
|
+
import { Response, Headers } from "cross-fetch";
|
|
39
39
|
import { JWK, importJWK } from "jose";
|
|
40
40
|
import { KeyObject } from "crypto";
|
|
41
41
|
import { AuthCodeRedirectHandler } from "./AuthCodeRedirectHandler";
|
|
@@ -470,11 +470,6 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
470
470
|
storageUtility: mockedStorage,
|
|
471
471
|
});
|
|
472
472
|
await authCodeRedirectHandler.handle(mockRedirectUrl());
|
|
473
|
-
await expect(
|
|
474
|
-
mockedStorage.getForUser("mySession", "redirectUrl", {
|
|
475
|
-
secure: false,
|
|
476
|
-
})
|
|
477
|
-
).resolves.toBe("https://some.redirect.uri/?state=oauth2StateValue");
|
|
478
473
|
|
|
479
474
|
// The ID token should not have been stored
|
|
480
475
|
await expect(
|
|
@@ -484,7 +479,7 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
484
479
|
).resolves.toBeUndefined();
|
|
485
480
|
});
|
|
486
481
|
|
|
487
|
-
it("
|
|
482
|
+
it("does not override the previously stored redirect URL", async () => {
|
|
488
483
|
mockOidcClient();
|
|
489
484
|
|
|
490
485
|
window.fetch = (jest.fn() as any).mockReturnValue(
|
|
@@ -509,9 +504,8 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
509
504
|
mockedStorage.getForUser("mySession", "redirectUrl", {
|
|
510
505
|
secure: false,
|
|
511
506
|
})
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
);
|
|
507
|
+
// The redirect URL already in storage shouldn't be overriden on redirect.
|
|
508
|
+
).resolves.toBe(DEFAULT_REDIRECT_URL);
|
|
515
509
|
});
|
|
516
510
|
|
|
517
511
|
it("returns the expiration time normalised to the current time", async () => {
|
|
@@ -175,19 +175,6 @@ export class AuthCodeRedirectHandler implements IIncomingRedirectHandler {
|
|
|
175
175
|
},
|
|
176
176
|
{ secure: true }
|
|
177
177
|
);
|
|
178
|
-
// Clear the code query param from the redirect URL before storing it, but
|
|
179
|
-
// preserve any state that my have been provided by the client and returned
|
|
180
|
-
// by the IdP.
|
|
181
|
-
url.searchParams.delete("code");
|
|
182
|
-
await this.storageUtility.setForUser(
|
|
183
|
-
storedSessionId,
|
|
184
|
-
{
|
|
185
|
-
redirectUrl: url.toString(),
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
secure: false,
|
|
189
|
-
}
|
|
190
|
-
);
|
|
191
178
|
|
|
192
179
|
const sessionInfo = await this.sessionInfoManager.get(storedSessionId);
|
|
193
180
|
if (!sessionInfo) {
|