@inrupt/solid-client-authn-browser 1.14.0 → 1.16.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 +1 -0
- package/dist/Session.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 +6 -8
- package/src/ClientAuthentication.spec.ts +15 -8
- package/src/ClientAuthentication.ts +2 -2
- package/src/Session.spec.ts +13 -5
- package/src/Session.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.16.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"types": "dist/index",
|
|
6
6
|
"browser": "dist/index.js",
|
|
@@ -25,10 +25,11 @@
|
|
|
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.16.0",
|
|
29
|
+
"@inrupt/solid-client-authn-core": "^1.16.0",
|
|
30
|
+
"@inrupt/universal-fetch": "^1.0.1",
|
|
30
31
|
"@types/lodash.clonedeep": "^4.5.6",
|
|
31
|
-
"@types/node": "^
|
|
32
|
+
"@types/node": "^20.1.0",
|
|
32
33
|
"@types/uuid": "^9.0.1",
|
|
33
34
|
"events": "^3.3.0",
|
|
34
35
|
"jose": "^4.3.7",
|
|
@@ -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": "fcdfb264ec59cfbeb0e2821ddb7fb716450c13e2"
|
|
42
|
+
"gitHead": "e0354ece5caa8863eb0704525b9a4abb2d2a6cfc"
|
|
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,6 +27,8 @@ 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";
|
|
@@ -36,6 +38,16 @@ 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
|
|
package/src/Session.ts
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
ISessionEventListener,
|
|
32
32
|
buildProxyHandler,
|
|
33
33
|
} from "@inrupt/solid-client-authn-core";
|
|
34
|
+
import { fetch } from "@inrupt/universal-fetch";
|
|
34
35
|
import { v4 } from "uuid";
|
|
35
36
|
import EventEmitter from "events";
|
|
36
37
|
import ClientAuthentication from "./ClientAuthentication";
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
mockStorageUtility,
|
|
25
25
|
} from "@inrupt/solid-client-authn-core/mocks";
|
|
26
26
|
import { jest, it, describe, expect } from "@jest/globals";
|
|
27
|
-
import { Response as NodeResponse } from "
|
|
27
|
+
import { Response as NodeResponse } from "@inrupt/universal-fetch";
|
|
28
28
|
import ClientRegistrar from "./ClientRegistrar";
|
|
29
29
|
import { IssuerConfigFetcherFetchConfigResponse } from "./__mocks__/IssuerConfigFetcher";
|
|
30
30
|
|
|
@@ -21,9 +21,20 @@
|
|
|
21
21
|
|
|
22
22
|
import { jest, it, describe, expect } from "@jest/globals";
|
|
23
23
|
import { mockStorageUtility } from "@inrupt/solid-client-authn-core";
|
|
24
|
-
import { Response as NodeResponse } from "
|
|
24
|
+
import { fetch, Response as NodeResponse } from "@inrupt/universal-fetch";
|
|
25
|
+
import * as UniversalFetch from "@inrupt/universal-fetch";
|
|
25
26
|
import IssuerConfigFetcher from "./IssuerConfigFetcher";
|
|
26
27
|
|
|
28
|
+
jest.mock("@inrupt/universal-fetch", () => {
|
|
29
|
+
const fetchModule = jest.requireActual(
|
|
30
|
+
"@inrupt/universal-fetch"
|
|
31
|
+
) as typeof UniversalFetch;
|
|
32
|
+
return {
|
|
33
|
+
...fetchModule,
|
|
34
|
+
fetch: jest.fn<typeof fetch>(),
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
|
|
27
38
|
/**
|
|
28
39
|
* Test for IssuerConfigFetcher
|
|
29
40
|
*/
|
|
@@ -41,19 +52,22 @@ describe("IssuerConfigFetcher", () => {
|
|
|
41
52
|
}
|
|
42
53
|
|
|
43
54
|
it("should return a config based on the fetched config if none was stored in the storage", async () => {
|
|
44
|
-
const fetchResponse = new NodeResponse(
|
|
45
|
-
JSON.stringify({
|
|
46
|
-
issuer: "https://example.com",
|
|
47
|
-
// eslint-disable-next-line camelcase
|
|
48
|
-
claim_types_supported: "oidc",
|
|
49
|
-
bleepBloop: "Meep Moop",
|
|
50
|
-
})
|
|
51
|
-
) as unknown as Response;
|
|
52
55
|
const configFetcher = getIssuerConfigFetcher({
|
|
53
56
|
storageUtility: mockStorageUtility({}),
|
|
54
57
|
});
|
|
55
|
-
const mockFetch =
|
|
56
|
-
|
|
58
|
+
const { fetch: mockFetch } = jest.requireMock(
|
|
59
|
+
"@inrupt/universal-fetch"
|
|
60
|
+
) as jest.Mocked<typeof UniversalFetch>;
|
|
61
|
+
mockFetch.mockResolvedValueOnce(
|
|
62
|
+
new NodeResponse(
|
|
63
|
+
JSON.stringify({
|
|
64
|
+
issuer: "https://example.com",
|
|
65
|
+
// eslint-disable-next-line camelcase
|
|
66
|
+
claim_types_supported: "oidc",
|
|
67
|
+
bleepBloop: "Meep Moop",
|
|
68
|
+
})
|
|
69
|
+
)
|
|
70
|
+
);
|
|
57
71
|
const fetchedConfig = await configFetcher.fetchConfig(
|
|
58
72
|
"https://arbitrary.url"
|
|
59
73
|
);
|
|
@@ -65,34 +79,34 @@ describe("IssuerConfigFetcher", () => {
|
|
|
65
79
|
});
|
|
66
80
|
|
|
67
81
|
it("should throw an error if the fetched config could not be converted to JSON", async () => {
|
|
68
|
-
const mockFetch = (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
},
|
|
73
|
-
} as unknown as Response);
|
|
74
|
-
window.fetch = mockFetch;
|
|
82
|
+
const { fetch: mockFetch } = jest.requireMock(
|
|
83
|
+
"@inrupt/universal-fetch"
|
|
84
|
+
) as jest.Mocked<typeof UniversalFetch>;
|
|
85
|
+
mockFetch.mockResolvedValueOnce(new NodeResponse("Not JSON."));
|
|
75
86
|
const configFetcher = new IssuerConfigFetcher(mockStorageUtility({}));
|
|
76
87
|
|
|
77
88
|
await expect(configFetcher.fetchConfig("https://some.url")).rejects.toThrow(
|
|
78
|
-
"[https://some.url] has an invalid configuration:
|
|
89
|
+
"[https://some.url] has an invalid configuration:"
|
|
79
90
|
);
|
|
80
91
|
});
|
|
81
92
|
|
|
82
93
|
it("should return a config including the support for solid-oidc if present in the discovery profile", async () => {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
94
|
+
const { fetch: mockFetch } = jest.requireMock(
|
|
95
|
+
"@inrupt/universal-fetch"
|
|
96
|
+
) as jest.Mocked<typeof UniversalFetch>;
|
|
97
|
+
mockFetch.mockResolvedValueOnce(
|
|
98
|
+
new NodeResponse(
|
|
99
|
+
JSON.stringify({
|
|
100
|
+
issuer: "https://example.com",
|
|
101
|
+
// eslint-disable-next-line camelcase
|
|
102
|
+
claim_types_supported: "oidc",
|
|
103
|
+
scopes_supported: ["openid", "offline_access", "webid"],
|
|
104
|
+
})
|
|
105
|
+
)
|
|
106
|
+
);
|
|
91
107
|
const configFetcher = getIssuerConfigFetcher({
|
|
92
108
|
storageUtility: mockStorageUtility({}),
|
|
93
109
|
});
|
|
94
|
-
const mockFetch = (jest.fn() as any).mockResolvedValueOnce(fetchResponse);
|
|
95
|
-
window.fetch = mockFetch as typeof window.fetch;
|
|
96
110
|
const fetchedConfig = await configFetcher.fetchConfig(
|
|
97
111
|
"https://arbitrary.url"
|
|
98
112
|
);
|
|
@@ -102,18 +116,21 @@ describe("IssuerConfigFetcher", () => {
|
|
|
102
116
|
});
|
|
103
117
|
|
|
104
118
|
it("should return a default value for the supported scopes if not advertized by the OpenID provider", async () => {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
119
|
+
const { fetch: mockFetch } = jest.requireMock(
|
|
120
|
+
"@inrupt/universal-fetch"
|
|
121
|
+
) as jest.Mocked<typeof UniversalFetch>;
|
|
122
|
+
mockFetch.mockResolvedValueOnce(
|
|
123
|
+
new NodeResponse(
|
|
124
|
+
JSON.stringify({
|
|
125
|
+
issuer: "https://example.com",
|
|
126
|
+
// eslint-disable-next-line camelcase
|
|
127
|
+
claim_types_supported: "oidc",
|
|
128
|
+
})
|
|
129
|
+
)
|
|
130
|
+
);
|
|
112
131
|
const configFetcher = getIssuerConfigFetcher({
|
|
113
132
|
storageUtility: mockStorageUtility({}),
|
|
114
133
|
});
|
|
115
|
-
const mockFetch = (jest.fn() as any).mockResolvedValueOnce(fetchResponse);
|
|
116
|
-
window.fetch = mockFetch as typeof window.fetch;
|
|
117
134
|
const fetchedConfig = await configFetcher.fetchConfig(
|
|
118
135
|
"https://arbitrary.url"
|
|
119
136
|
);
|
|
@@ -122,17 +139,20 @@ describe("IssuerConfigFetcher", () => {
|
|
|
122
139
|
|
|
123
140
|
it("should append the .well-known/openid-configuration path at the end of the issuer URL", async () => {
|
|
124
141
|
// The response value is irrelevant to this test.
|
|
125
|
-
const mockFetch = jest.
|
|
142
|
+
const { fetch: mockFetch } = jest.requireMock(
|
|
143
|
+
"@inrupt/universal-fetch"
|
|
144
|
+
) as jest.Mocked<typeof UniversalFetch>;
|
|
145
|
+
mockFetch.mockImplementation(
|
|
126
146
|
async () =>
|
|
127
147
|
new NodeResponse(
|
|
128
148
|
JSON.stringify({
|
|
129
149
|
issuer: "https://example.com",
|
|
130
150
|
// eslint-disable-next-line camelcase
|
|
131
151
|
claim_types_supported: "oidc",
|
|
152
|
+
scopes_supported: ["openid", "offline_access", "webid"],
|
|
132
153
|
})
|
|
133
154
|
)
|
|
134
155
|
);
|
|
135
|
-
window.fetch = mockFetch as typeof window.fetch;
|
|
136
156
|
const configFetcher = getIssuerConfigFetcher({
|
|
137
157
|
storageUtility: mockStorageUtility({}),
|
|
138
158
|
});
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
IStorageUtility,
|
|
34
34
|
ConfigurationError,
|
|
35
35
|
} from "@inrupt/solid-client-authn-core";
|
|
36
|
+
import { fetch } from "@inrupt/universal-fetch";
|
|
36
37
|
|
|
37
38
|
export const WELL_KNOWN_OPENID_CONFIG = ".well-known/openid-configuration";
|
|
38
39
|
|
|
@@ -165,7 +166,7 @@ export default class IssuerConfigFetcher implements IIssuerConfigFetcher {
|
|
|
165
166
|
// includes the full issuer path. See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig.
|
|
166
167
|
issuer.endsWith("/") ? issuer : `${issuer}/`
|
|
167
168
|
).href;
|
|
168
|
-
const issuerConfigRequestBody = await
|
|
169
|
+
const issuerConfigRequestBody = await fetch(openIdConfigUrl);
|
|
169
170
|
// Check the validity of the fetched config
|
|
170
171
|
try {
|
|
171
172
|
issuerConfig = processConfig(await issuerConfigRequestBody.json());
|
|
@@ -35,7 +35,8 @@ 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, Headers } from "
|
|
38
|
+
import { fetch, Response, Headers } from "@inrupt/universal-fetch";
|
|
39
|
+
import * as UniversalFetch from "@inrupt/universal-fetch";
|
|
39
40
|
import { JWK, importJWK } from "jose";
|
|
40
41
|
import { KeyObject } from "crypto";
|
|
41
42
|
import { AuthCodeRedirectHandler } from "./AuthCodeRedirectHandler";
|
|
@@ -46,6 +47,16 @@ import {
|
|
|
46
47
|
mockTokenRefresher,
|
|
47
48
|
} from "../refresh/__mocks__/TokenRefresher";
|
|
48
49
|
|
|
50
|
+
jest.mock("@inrupt/universal-fetch", () => {
|
|
51
|
+
const fetchModule = jest.requireActual(
|
|
52
|
+
"@inrupt/universal-fetch"
|
|
53
|
+
) as typeof UniversalFetch;
|
|
54
|
+
return {
|
|
55
|
+
...fetchModule,
|
|
56
|
+
fetch: jest.fn<typeof fetch>(),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
|
|
49
60
|
const mockJwk = (): JWK => {
|
|
50
61
|
return {
|
|
51
62
|
kty: "EC",
|
|
@@ -193,8 +204,10 @@ function mockClientRegistrar(client: IClient): IClientRegistrar {
|
|
|
193
204
|
}
|
|
194
205
|
|
|
195
206
|
const mockFetch = (response: Response) => {
|
|
196
|
-
const mockedFetch = jest.
|
|
197
|
-
|
|
207
|
+
const { fetch: mockedFetch } = jest.requireMock(
|
|
208
|
+
"@inrupt/universal-fetch"
|
|
209
|
+
) as jest.Mocked<typeof UniversalFetch>;
|
|
210
|
+
mockedFetch.mockResolvedValueOnce(response);
|
|
198
211
|
return mockedFetch;
|
|
199
212
|
};
|
|
200
213
|
|
|
@@ -405,7 +418,7 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
405
418
|
|
|
406
419
|
it("returns an authenticated bearer fetch if requested", async () => {
|
|
407
420
|
mockOidcClient();
|
|
408
|
-
const mockedFetch = jest.mocked<typeof fetch>(
|
|
421
|
+
const mockedFetch = jest.mocked<typeof fetch>(fetch);
|
|
409
422
|
mockedFetch.mockResolvedValueOnce(
|
|
410
423
|
new Response("", {
|
|
411
424
|
status: 200,
|
|
@@ -433,7 +446,7 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
433
446
|
|
|
434
447
|
it("returns an authenticated DPoP fetch if requested", async () => {
|
|
435
448
|
mockOidcClient();
|
|
436
|
-
const mockedFetch = jest.mocked<typeof fetch>(
|
|
449
|
+
const mockedFetch = jest.mocked<typeof fetch>(fetch);
|
|
437
450
|
mockedFetch.mockResolvedValueOnce(
|
|
438
451
|
new Response("", {
|
|
439
452
|
status: 200,
|
|
@@ -454,13 +467,9 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
454
467
|
|
|
455
468
|
it("saves session information in storage on successful login", async () => {
|
|
456
469
|
mockOidcClient();
|
|
457
|
-
|
|
458
|
-
new
|
|
459
|
-
|
|
460
|
-
new Response("", {
|
|
461
|
-
status: 200,
|
|
462
|
-
})
|
|
463
|
-
);
|
|
470
|
+
mockFetch(
|
|
471
|
+
new Response("", {
|
|
472
|
+
status: 200,
|
|
464
473
|
})
|
|
465
474
|
);
|
|
466
475
|
|
|
@@ -482,15 +491,11 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
482
491
|
it("does not override the previously stored redirect URL", async () => {
|
|
483
492
|
mockOidcClient();
|
|
484
493
|
|
|
485
|
-
|
|
486
|
-
new
|
|
487
|
-
|
|
488
|
-
new Response("", {
|
|
489
|
-
status: 200,
|
|
490
|
-
})
|
|
491
|
-
);
|
|
494
|
+
mockFetch(
|
|
495
|
+
new Response("", {
|
|
496
|
+
status: 200,
|
|
492
497
|
})
|
|
493
|
-
)
|
|
498
|
+
);
|
|
494
499
|
|
|
495
500
|
const mockedStorage = mockDefaultStorageUtility();
|
|
496
501
|
|
|
@@ -510,7 +515,7 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
510
515
|
|
|
511
516
|
it("returns the expiration time normalised to the current time", async () => {
|
|
512
517
|
mockOidcClient();
|
|
513
|
-
|
|
518
|
+
mockFetch(new Response());
|
|
514
519
|
const MOCK_TIMESTAMP = 10000;
|
|
515
520
|
Date.now = jest
|
|
516
521
|
.fn()
|
|
@@ -533,7 +538,7 @@ describe("AuthCodeRedirectHandler", () => {
|
|
|
533
538
|
|
|
534
539
|
it("returns null for the expiration time if none was provided", async () => {
|
|
535
540
|
const mockedOidcClient = mockOidcClient();
|
|
536
|
-
|
|
541
|
+
mockFetch(new Response());
|
|
537
542
|
mockedOidcClient.getBearerToken = jest
|
|
538
543
|
.fn(getBearerToken)
|
|
539
544
|
.mockResolvedValueOnce({
|
|
@@ -22,8 +22,20 @@
|
|
|
22
22
|
import { jest, it, describe, expect } from "@jest/globals";
|
|
23
23
|
import { EventEmitter } from "events";
|
|
24
24
|
import { EVENTS } from "@inrupt/solid-client-authn-core";
|
|
25
|
+
import { fetch } from "@inrupt/universal-fetch";
|
|
26
|
+
import * as UniversalFetch from "@inrupt/universal-fetch";
|
|
25
27
|
import { ErrorOidcHandler } from "./ErrorOidcHandler";
|
|
26
28
|
|
|
29
|
+
jest.mock("@inrupt/universal-fetch", () => {
|
|
30
|
+
const fetchModule = jest.requireActual(
|
|
31
|
+
"@inrupt/universal-fetch"
|
|
32
|
+
) as typeof UniversalFetch;
|
|
33
|
+
return {
|
|
34
|
+
...fetchModule,
|
|
35
|
+
fetch: jest.fn<typeof fetch>(),
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
|
|
27
39
|
describe("ErrorOidcHandler", () => {
|
|
28
40
|
describe("canHandle", () => {
|
|
29
41
|
it("Does not handle IRIs without an error parameter", async () => {
|
|
@@ -62,14 +74,12 @@ describe("ErrorOidcHandler", () => {
|
|
|
62
74
|
|
|
63
75
|
describe("handle", () => {
|
|
64
76
|
it("returns an unauthenticated session", async () => {
|
|
65
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
66
77
|
const redirectHandler = new ErrorOidcHandler();
|
|
67
78
|
const mySession = await redirectHandler.handle("https://my.app");
|
|
68
79
|
expect(mySession.isLoggedIn).toBe(false);
|
|
69
80
|
expect(mySession.webId).toBeUndefined();
|
|
70
81
|
});
|
|
71
82
|
it("calls the onError callback if given with both parameters", async () => {
|
|
72
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
73
83
|
const mockEmitter = new EventEmitter();
|
|
74
84
|
// error events must be handled: https://nodejs.org/dist/latest-v16.x/docs/api/events.html#error-events
|
|
75
85
|
mockEmitter.on(EVENTS.ERROR, jest.fn());
|
|
@@ -90,7 +100,6 @@ describe("ErrorOidcHandler", () => {
|
|
|
90
100
|
});
|
|
91
101
|
|
|
92
102
|
it("calls the onError callback if given with just error parameters if no description is provided", async () => {
|
|
93
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
94
103
|
const mockEmitter = new EventEmitter();
|
|
95
104
|
const mockEmit = jest.spyOn(mockEmitter, "emit");
|
|
96
105
|
// error events must be handled: https://nodejs.org/dist/latest-v16.x/docs/api/events.html#error-events
|
|
@@ -20,8 +20,20 @@
|
|
|
20
20
|
//
|
|
21
21
|
|
|
22
22
|
import { jest, it, describe, expect } from "@jest/globals";
|
|
23
|
+
import { fetch } from "@inrupt/universal-fetch";
|
|
24
|
+
import * as UniversalFetch from "@inrupt/universal-fetch";
|
|
23
25
|
import { FallbackRedirectHandler } from "./FallbackRedirectHandler";
|
|
24
26
|
|
|
27
|
+
jest.mock("@inrupt/universal-fetch", () => {
|
|
28
|
+
const fetchModule = jest.requireActual(
|
|
29
|
+
"@inrupt/universal-fetch"
|
|
30
|
+
) as typeof UniversalFetch;
|
|
31
|
+
return {
|
|
32
|
+
...fetchModule,
|
|
33
|
+
fetch: jest.fn<typeof fetch>(),
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
|
|
25
37
|
describe("FallbackRedirectHandler", () => {
|
|
26
38
|
describe("canHandle", () => {
|
|
27
39
|
it("always accept the given IRI", async () => {
|
|
@@ -51,7 +63,6 @@ describe("FallbackRedirectHandler", () => {
|
|
|
51
63
|
|
|
52
64
|
describe("handle", () => {
|
|
53
65
|
it("returns an unauthenticated session", async () => {
|
|
54
|
-
window.fetch = jest.fn<typeof fetch>();
|
|
55
66
|
const redirectHandler = new FallbackRedirectHandler();
|
|
56
67
|
const mySession = await redirectHandler.handle("https://my.app");
|
|
57
68
|
expect(mySession.isLoggedIn).toBe(false);
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
} from "@inrupt/solid-client-authn-core";
|
|
35
35
|
import { v4 } from "uuid";
|
|
36
36
|
import { clearOidcPersistentStorage } from "@inrupt/oidc-client-ext";
|
|
37
|
+
import { fetch } from "@inrupt/universal-fetch";
|
|
37
38
|
|
|
38
39
|
export function getUnauthenticatedSession(): ISessionInfo & {
|
|
39
40
|
fetch: typeof fetch;
|
package/tsconfig.json
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
"typedocOptions": {
|
|
10
10
|
"out": "website/docs/api/browser",
|
|
11
11
|
"entryPoints": ["./src/index.ts"],
|
|
12
|
-
"entryDocument": "index.
|
|
12
|
+
"entryDocument": "index.rst",
|
|
13
13
|
"hideInPageTOC": true,
|
|
14
|
+
"plugin": ["typedoc-plugin-markdown"]
|
|
14
15
|
},
|
|
15
16
|
|
|
16
17
|
"include": ["src/**/*"],
|