@inrupt/solid-client-authn-browser 1.13.2 → 1.13.4
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/login/oidc/IssuerConfigFetcher.js +1 -1
- package/dist/login/oidc/IssuerConfigFetcher.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 +5 -5
- package/src/Session.spec.ts +10 -9
- package/src/login/oidc/IssuerConfigFetcher.spec.ts +38 -0
- package/src/login/oidc/IssuerConfigFetcher.ts +6 -1
- package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.spec.ts +4 -10
- package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.ts +0 -13
- 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.13.
|
|
3
|
+
"version": "1.13.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"types": "dist/index",
|
|
6
6
|
"browser": "dist/index.js",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"cross-fetch": "^3.1.5"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@inrupt/oidc-client-ext": "^1.13.
|
|
29
|
-
"@inrupt/solid-client-authn-core": "^1.13.
|
|
28
|
+
"@inrupt/oidc-client-ext": "^1.13.4",
|
|
29
|
+
"@inrupt/solid-client-authn-core": "^1.13.4",
|
|
30
30
|
"@types/lodash.clonedeep": "^4.5.6",
|
|
31
31
|
"@types/node": "^18.0.3",
|
|
32
|
-
"@types/uuid": "^
|
|
32
|
+
"@types/uuid": "^9.0.1",
|
|
33
33
|
"events": "^3.3.0",
|
|
34
34
|
"jose": "^4.3.7",
|
|
35
35
|
"lodash.clonedeep": "^4.5.0",
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"engines": {
|
|
42
42
|
"node": "^14.0.0 || ^16.0.0"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "ab437bbfb613f4f64b82b17e3a38177998a1762a"
|
|
45
45
|
}
|
package/src/Session.spec.ts
CHANGED
|
@@ -32,6 +32,7 @@ import { Session } from "./Session";
|
|
|
32
32
|
import { LocalStorageMock } from "./storage/__mocks__/LocalStorage";
|
|
33
33
|
import { mockSessionInfoManager } from "./sessionInfo/__mocks__/SessionInfoManager";
|
|
34
34
|
import { KEY_CURRENT_SESSION, KEY_CURRENT_URL } from "./constant";
|
|
35
|
+
import type ClientAuthentication from "./ClientAuthentication";
|
|
35
36
|
|
|
36
37
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
37
38
|
|
|
@@ -264,21 +265,21 @@ describe("Session", () => {
|
|
|
264
265
|
|
|
265
266
|
it("updates the session's info if relevant", async () => {
|
|
266
267
|
const clientAuthentication = mockClientAuthentication();
|
|
267
|
-
clientAuthentication.handleIncomingRedirect = jest
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
);
|
|
268
|
+
clientAuthentication.handleIncomingRedirect = jest
|
|
269
|
+
.fn<ClientAuthentication["handleIncomingRedirect"]>()
|
|
270
|
+
.mockResolvedValueOnce({
|
|
271
|
+
isLoggedIn: true,
|
|
272
|
+
sessionId: "a session ID",
|
|
273
|
+
webId: "https://some.webid#them",
|
|
274
|
+
expirationDate: Date.now() + 3600,
|
|
275
|
+
});
|
|
276
276
|
const mySession = new Session({ clientAuthentication });
|
|
277
277
|
expect(mySession.info.isLoggedIn).toBe(false);
|
|
278
278
|
await mySession.handleIncomingRedirect("https://some.url");
|
|
279
279
|
expect(mySession.info.isLoggedIn).toBe(true);
|
|
280
280
|
expect(mySession.info.sessionId).toBe("a session ID");
|
|
281
281
|
expect(mySession.info.webId).toBe("https://some.webid#them");
|
|
282
|
+
expect(mySession.info.expirationDate).toBeGreaterThan(Date.now());
|
|
282
283
|
});
|
|
283
284
|
|
|
284
285
|
it("updates the localStorage if the login is completed", async () => {
|
|
@@ -119,4 +119,42 @@ describe("IssuerConfigFetcher", () => {
|
|
|
119
119
|
);
|
|
120
120
|
expect(fetchedConfig.scopesSupported).toContain("openid");
|
|
121
121
|
});
|
|
122
|
+
|
|
123
|
+
it("should append the .well-known/openid-configuration path at the end of the issuer URL", async () => {
|
|
124
|
+
// The response value is irrelevant to this test.
|
|
125
|
+
const mockFetch = jest.fn<typeof fetch>().mockImplementation(
|
|
126
|
+
async () =>
|
|
127
|
+
new NodeResponse(
|
|
128
|
+
JSON.stringify({
|
|
129
|
+
issuer: "https://example.com",
|
|
130
|
+
// eslint-disable-next-line camelcase
|
|
131
|
+
claim_types_supported: "oidc",
|
|
132
|
+
})
|
|
133
|
+
)
|
|
134
|
+
);
|
|
135
|
+
window.fetch = mockFetch as typeof window.fetch;
|
|
136
|
+
const configFetcher = getIssuerConfigFetcher({
|
|
137
|
+
storageUtility: mockStorageUtility({}),
|
|
138
|
+
});
|
|
139
|
+
// No trailing slash
|
|
140
|
+
await configFetcher.fetchConfig("https://arbitrary.url");
|
|
141
|
+
expect(mockFetch).toHaveBeenLastCalledWith(
|
|
142
|
+
"https://arbitrary.url/.well-known/openid-configuration"
|
|
143
|
+
);
|
|
144
|
+
// A trailing slash
|
|
145
|
+
await configFetcher.fetchConfig("https://arbitrary.url/");
|
|
146
|
+
expect(mockFetch).toHaveBeenLastCalledWith(
|
|
147
|
+
"https://arbitrary.url/.well-known/openid-configuration"
|
|
148
|
+
);
|
|
149
|
+
// A path without a trailing slash
|
|
150
|
+
await configFetcher.fetchConfig("https://arbitrary.url/path");
|
|
151
|
+
expect(mockFetch).toHaveBeenLastCalledWith(
|
|
152
|
+
"https://arbitrary.url/path/.well-known/openid-configuration"
|
|
153
|
+
);
|
|
154
|
+
// A path with a trailing slash
|
|
155
|
+
await configFetcher.fetchConfig("https://arbitrary.url/path/");
|
|
156
|
+
expect(mockFetch).toHaveBeenLastCalledWith(
|
|
157
|
+
"https://arbitrary.url/path/.well-known/openid-configuration"
|
|
158
|
+
);
|
|
159
|
+
});
|
|
122
160
|
});
|
|
@@ -159,7 +159,12 @@ export default class IssuerConfigFetcher implements IIssuerConfigFetcher {
|
|
|
159
159
|
async fetchConfig(issuer: string): Promise<IIssuerConfig> {
|
|
160
160
|
let issuerConfig: IIssuerConfig;
|
|
161
161
|
|
|
162
|
-
const openIdConfigUrl = new URL(
|
|
162
|
+
const openIdConfigUrl = new URL(
|
|
163
|
+
WELL_KNOWN_OPENID_CONFIG,
|
|
164
|
+
// Make sure to append a slash at issuer URL, so that the .well-known URL
|
|
165
|
+
// includes the full issuer path. See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig.
|
|
166
|
+
issuer.endsWith("/") ? issuer : `${issuer}/`
|
|
167
|
+
).href;
|
|
163
168
|
const issuerConfigRequestBody = await window.fetch(openIdConfigUrl);
|
|
164
169
|
// Check the validity of the fetched config
|
|
165
170
|
try {
|
|
@@ -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) {
|