@inrupt/solid-client-authn-browser 3.1.1 → 5.0.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.
Files changed (65) hide show
  1. package/README.md +9 -13
  2. package/dist/index.js +28 -38
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +28 -38
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/solid-client-authn.bundle.js +1 -31
  7. package/dist/solid-client-authn.bundle.js.map +1 -1
  8. package/package.json +7 -7
  9. package/rollup.config.mjs +0 -2
  10. package/src/ClientAuthentication.spec.ts +147 -23
  11. package/src/ClientAuthentication.ts +18 -4
  12. package/src/Session.spec.ts +74 -39
  13. package/src/Session.ts +0 -1
  14. package/src/__mocks__/ClientAuthentication.ts +1 -1
  15. package/src/constant.ts +0 -1
  16. package/src/defaultSession.spec.ts +0 -1
  17. package/src/defaultSession.ts +1 -2
  18. package/src/dependencies.node.spec.ts +0 -1
  19. package/src/dependencies.spec.ts +0 -1
  20. package/src/dependencies.ts +0 -1
  21. package/src/index.browser.spec.ts +0 -1
  22. package/src/index.browser.ts +0 -1
  23. package/src/index.spec.ts +0 -1
  24. package/src/index.ts +0 -1
  25. package/src/login/__mocks__/LoginHandler.ts +0 -1
  26. package/src/login/oidc/AggregateOidcHandler.spec.ts +1 -2
  27. package/src/login/oidc/AggregateOidcHandler.ts +0 -1
  28. package/src/login/oidc/AggregateRedirectHandler.ts +0 -1
  29. package/src/login/oidc/ClientRegistrar.spec.ts +1 -1
  30. package/src/login/oidc/ClientRegistrar.ts +0 -1
  31. package/src/login/oidc/IssuerConfigFetcher.spec.ts +7 -5
  32. package/src/login/oidc/IssuerConfigFetcher.ts +3 -3
  33. package/src/login/oidc/OidcLoginHandler.spec.ts +1 -1
  34. package/src/login/oidc/OidcLoginHandler.ts +0 -1
  35. package/src/login/oidc/Redirector.spec.ts +5 -23
  36. package/src/login/oidc/Redirector.ts +0 -1
  37. package/src/login/oidc/__mocks__/ClientRegistrar.ts +0 -1
  38. package/src/login/oidc/__mocks__/IOidcHandler.ts +1 -3
  39. package/src/login/oidc/__mocks__/IOidcOptions.ts +0 -1
  40. package/src/login/oidc/__mocks__/IssuerConfigFetcher.ts +0 -2
  41. package/src/login/oidc/__mocks__/Redirector.ts +0 -1
  42. package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.spec.ts +3 -4
  43. package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.ts +0 -1
  44. package/src/login/oidc/incomingRedirectHandler/ErrorOidcHandler.spec.ts +0 -1
  45. package/src/login/oidc/incomingRedirectHandler/ErrorOidcHandler.ts +0 -2
  46. package/src/login/oidc/incomingRedirectHandler/FallbackRedirectHandler.spec.ts +0 -1
  47. package/src/login/oidc/incomingRedirectHandler/FallbackRedirectHandler.ts +1 -2
  48. package/src/login/oidc/oidcHandlers/AuthorizationCodeWithPkceOidcHandler.spec.ts +1 -4
  49. package/src/login/oidc/oidcHandlers/AuthorizationCodeWithPkceOidcHandler.ts +10 -11
  50. package/src/login/oidc/oidcHandlers/OidcHandlerCanHandleTest.ts +0 -1
  51. package/src/login/oidc/refresh/TokenRefresher.spec.ts +3 -4
  52. package/src/login/oidc/refresh/TokenRefresher.ts +0 -2
  53. package/src/login/oidc/refresh/__mocks__/TokenRefresher.ts +0 -2
  54. package/src/logout/buildRpInitiatedLogout.ts +1 -1
  55. package/src/sessionInfo/SessionInfoManager.spec.ts +62 -1
  56. package/src/sessionInfo/SessionInfoManager.ts +6 -1
  57. package/src/sessionInfo/__mocks__/SessionInfoManager.ts +1 -2
  58. package/src/storage/BrowserStorage.spec.ts +0 -1
  59. package/src/storage/BrowserStorage.ts +0 -1
  60. package/src/storage/StorageUtility.ts +0 -1
  61. package/src/storage/__mocks__/LocalStorage.ts +0 -1
  62. package/src/util/UUIDGenerator.spec.ts +0 -1
  63. package/src/util/UuidGenerator.ts +0 -2
  64. package/src/util/__mocks__/UuidGenerator.ts +0 -1
  65. package/typedoc.config.mjs +0 -1
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
package/src/index.spec.ts CHANGED
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,7 +28,7 @@ jest.mock("@inrupt/solid-client-authn-core");
29
28
  describe("AggregateOidcHandler", () => {
30
29
  it("should pass injected handlers to its superclass", () => {
31
30
  // We just test if the parent is called.
32
- // eslint-disable-next-line no-new
31
+
33
32
  new AggregateOidcHandler(["Some handler"] as unknown as IOidcHandler[]);
34
33
 
35
34
  expect((AggregateHandler as jest.Mock).mock.calls).toEqual([
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -22,6 +21,7 @@
22
21
  import {
23
22
  StorageUtilityMock,
24
23
  mockStorageUtility,
24
+ // eslint-disable-next-line import/no-unresolved
25
25
  } from "@inrupt/solid-client-authn-core/mocks";
26
26
  import { jest, it, describe, expect } from "@jest/globals";
27
27
  import { randomUUID } from "crypto";
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -23,6 +22,9 @@ import { jest, it, describe, expect } from "@jest/globals";
23
22
  import { mockStorageUtility } from "@inrupt/solid-client-authn-core";
24
23
  import IssuerConfigFetcher from "./IssuerConfigFetcher";
25
24
 
25
+ // Camelcase identifiers are required in the OIDC specification.
26
+ /* eslint-disable camelcase*/
27
+
26
28
  /**
27
29
  * Test for IssuerConfigFetcher
28
30
  */
@@ -58,7 +60,7 @@ describe("IssuerConfigFetcher", () => {
58
60
  new Response(
59
61
  JSON.stringify({
60
62
  issuer: "https://example.com",
61
- // eslint-disable-next-line camelcase
63
+
62
64
  claim_types_supported: "oidc",
63
65
  bleepBloop: "Meep Moop",
64
66
  end_session_endpoint: "https://example.com/endSessionEndpoint",
@@ -92,7 +94,7 @@ describe("IssuerConfigFetcher", () => {
92
94
  new Response(
93
95
  JSON.stringify({
94
96
  issuer: "https://example.com",
95
- // eslint-disable-next-line camelcase
97
+
96
98
  claim_types_supported: "oidc",
97
99
  scopes_supported: ["openid", "offline_access", "webid"],
98
100
  }),
@@ -114,7 +116,7 @@ describe("IssuerConfigFetcher", () => {
114
116
  new Response(
115
117
  JSON.stringify({
116
118
  issuer: "https://example.com",
117
- // eslint-disable-next-line camelcase
119
+
118
120
  claim_types_supported: "oidc",
119
121
  }),
120
122
  ),
@@ -136,7 +138,7 @@ describe("IssuerConfigFetcher", () => {
136
138
  new Response(
137
139
  JSON.stringify({
138
140
  issuer: "https://example.com",
139
- // eslint-disable-next-line camelcase
141
+
140
142
  claim_types_supported: "oidc",
141
143
  scopes_supported: ["openid", "offline_access", "webid"],
142
144
  }),
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -34,9 +33,11 @@ import type {
34
33
  } from "@inrupt/solid-client-authn-core";
35
34
  import { ConfigurationError } from "@inrupt/solid-client-authn-core";
36
35
 
36
+ // Camelcase identifiers are required in the OIDC specification.
37
+ /* eslint-disable camelcase*/
38
+
37
39
  export const WELL_KNOWN_OPENID_CONFIG = ".well-known/openid-configuration";
38
40
 
39
- /* eslint-disable camelcase */
40
41
  const issuerConfigKeyMap: Record<
41
42
  string,
42
43
  { toKey: string; convertToUrl?: boolean }
@@ -127,7 +128,6 @@ const issuerConfigKeyMap: Record<
127
128
  convertToUrl: true,
128
129
  },
129
130
  };
130
- /* eslint-enable camelcase */
131
131
 
132
132
  function processConfig(
133
133
  config: Record<string, string | string[]>,
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -25,6 +24,7 @@ import { StorageUtility } from "@inrupt/solid-client-authn-core";
25
24
  import {
26
25
  StorageUtilityMock,
27
26
  mockStorage,
27
+ // eslint-disable-next-line import/no-unresolved
28
28
  } from "@inrupt/solid-client-authn-core/mocks";
29
29
  import { randomUUID } from "crypto";
30
30
 
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -32,39 +31,23 @@ import Redirector from "./Redirector";
32
31
  /**
33
32
  * Test for Redirector
34
33
  */
34
+ declare const __setTestUrl: (url: string) => void;
35
+
35
36
  describe("Redirector", () => {
36
37
  describe("redirect", () => {
37
- const {
38
- location,
39
- history: { replaceState },
40
- } = window;
41
-
42
38
  beforeEach(() => {
43
- // location and history aren't optional on window, which makes TS complain
44
- // (rightfully) when we delete them. However, they are deleted on purpose
45
- // here just for testing.
46
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
47
- // @ts-ignore
48
- delete window.location;
49
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
50
- // @ts-ignore
51
- delete window.history.replaceState;
52
- (window as any).location = {
53
- href: "https://coolSite.com",
54
- } as Location;
55
- window.history.replaceState = jest.fn();
39
+ __setTestUrl("https://coolSite.com");
40
+ jest.spyOn(window.history, "replaceState").mockImplementation(() => {});
56
41
  });
57
42
 
58
43
  afterEach(() => {
59
- (window as any).location = location;
60
- window.history.replaceState = replaceState;
44
+ jest.restoreAllMocks();
61
45
  });
62
46
 
63
47
  it("browser redirection defaults to using href", () => {
64
48
  const redirector = new Redirector();
65
49
  redirector.redirect("https://someUrl.com/redirect");
66
50
  expect(window.history.replaceState).not.toHaveBeenCalled();
67
- expect(window.location.href).toBe("https://someUrl.com/redirect");
68
51
  });
69
52
 
70
53
  it("browser redirection uses replaceState if specified", () => {
@@ -77,7 +60,6 @@ describe("Redirector", () => {
77
60
  "",
78
61
  "https://someUrl.com/redirect",
79
62
  );
80
- expect(window.location.href).toBe("https://coolSite.com");
81
63
  });
82
64
 
83
65
  it("calls redirect handler", () => {
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -32,9 +31,8 @@ export const OidcHandlerHandleResponse: ISessionInfo =
32
31
  SessionCreatorGetSessionResponse;
33
32
 
34
33
  export const OidcHandlerMock: jest.Mocked<IOidcHandler> = {
35
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
36
34
  canHandle: jest.fn((_options: IOidcOptions) => Promise.resolve(true)),
37
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
35
+
38
36
  handle: jest.fn(async (_options: IOidcOptions) => Promise.resolve(undefined)),
39
37
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
38
  } as any;
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -38,7 +37,6 @@ export const IssuerConfigFetcherFetchConfigResponse: IIssuerConfig = {
38
37
  };
39
38
 
40
39
  export const IssuerConfigFetcherMock: jest.Mocked<IIssuerConfigFetcher> = {
41
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
42
40
  fetchConfig: jest.fn((_issuer: string) =>
43
41
  Promise.resolve(IssuerConfigFetcherFetchConfigResponse),
44
42
  ),
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -31,12 +30,12 @@ import { USER_SESSION_PREFIX } from "@inrupt/solid-client-authn-core";
31
30
  import {
32
31
  StorageUtilityMock,
33
32
  mockStorageUtility,
33
+ // eslint-disable-next-line import/no-unresolved
34
34
  } from "@inrupt/solid-client-authn-core/mocks";
35
35
  import { jest, it, describe, expect } from "@jest/globals";
36
36
  import type * as OidcClientExt from "@inrupt/oidc-client-ext";
37
- import type { JWK } from "jose";
37
+ import type { JWK, CryptoKey } from "jose";
38
38
  import { importJWK } from "jose";
39
- import type { KeyObject } from "crypto";
40
39
  import { AuthCodeRedirectHandler } from "./AuthCodeRedirectHandler";
41
40
  import { SessionInfoManagerMock } from "../../../sessionInfo/__mocks__/SessionInfoManager";
42
41
  import { LocalStorageMock } from "../../../storage/__mocks__/LocalStorage";
@@ -126,7 +125,7 @@ const mockTokenEndpointDpopResponse =
126
125
  webId: mockWebId(),
127
126
  clientId: "some client",
128
127
  dpopKey: {
129
- privateKey: (await importJWK(mockJwk())) as KeyObject,
128
+ privateKey: (await importJWK(mockJwk())) as CryptoKey,
130
129
  // Note that here for convenience the private key is also used as public key.
131
130
  // Obviously, this should never be done in non-test code.
132
131
  publicKey: mockJwk(),
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -42,7 +41,6 @@ import { getUnauthenticatedSession } from "../../../sessionInfo/SessionInfoManag
42
41
  export class ErrorOidcHandler implements IIncomingRedirectHandler {
43
42
  async canHandle(redirectUrl: string): Promise<boolean> {
44
43
  try {
45
- // eslint-disable-next-line no-new
46
44
  return new URL(redirectUrl).searchParams.has("error");
47
45
  } catch (e) {
48
46
  throw new Error(
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -41,7 +40,7 @@ export class FallbackRedirectHandler implements IIncomingRedirectHandler {
41
40
  async canHandle(redirectUrl: string): Promise<boolean> {
42
41
  try {
43
42
  // The next URL object is built for validating it.
44
- // eslint-disable-next-line no-new
43
+
45
44
  new URL(redirectUrl);
46
45
  return true;
47
46
  } catch (e) {
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -33,6 +32,7 @@ import { StorageUtility } from "@inrupt/solid-client-authn-core";
33
32
  import {
34
33
  StorageUtilityMock,
35
34
  mockStorage,
35
+ // eslint-disable-next-line import/no-unresolved
36
36
  } from "@inrupt/solid-client-authn-core/mocks";
37
37
 
38
38
  import AuthorizationCodeWithPkceOidcHandler from "./AuthorizationCodeWithPkceOidcHandler";
@@ -53,7 +53,6 @@ const mockOidcModule = (
53
53
  url: string = expectedSigninRedirectUrl,
54
54
  state = "test state",
55
55
  ) => {
56
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
56
  const oidcModule = jest.requireMock("@inrupt/oidc-client-ext") as any;
58
57
  oidcModule.OidcClient.mockReturnValue({
59
58
  createSigninRequest: jest
@@ -91,7 +90,6 @@ describe("AuthorizationCodeWithPkceOidcHandler", () => {
91
90
  getAuthorizationCodeWithPkceOidcHandler();
92
91
  canHandleTests.authorizationCodeWithPkceOidcHandler.forEach(
93
92
  (testConfig) => {
94
- // eslint-disable-next-line jest/valid-title
95
93
  it(testConfig.message, async () => {
96
94
  const value = await authorizationCodeWithPkceOidcHandler.canHandle(
97
95
  testConfig.oidcOptions,
@@ -138,7 +136,6 @@ describe("AuthorizationCodeWithPkceOidcHandler", () => {
138
136
  // pretty nasty due to an Error instance being logged without being
139
137
  // converted to a string:
140
138
 
141
- // eslint-disable-next-line no-console
142
139
  expect(console.error).toHaveBeenCalledTimes(1);
143
140
  expect(
144
141
  (console as jest.Mocked<Console>).error.mock.calls[0][0].toString(),
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -35,6 +34,9 @@ import type {
35
34
  import { AuthorizationCodeWithPkceOidcHandlerBase } from "@inrupt/solid-client-authn-core";
36
35
  import { OidcClient } from "@inrupt/oidc-client-ext";
37
36
 
37
+ // Camelcase identifiers are required in the OIDC specification.
38
+ /* eslint-disable camelcase*/
39
+
38
40
  /**
39
41
  * @hidden
40
42
  * Authorization code flow spec: https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth
@@ -45,12 +47,12 @@ export default class AuthorizationCodeWithPkceOidcHandler
45
47
  implements IOidcHandler
46
48
  {
47
49
  async handle(oidcLoginOptions: IOidcOptions): Promise<LoginResult> {
48
- /* eslint-disable camelcase */
50
+ const redirectUri = oidcLoginOptions.redirectUrl ?? "";
49
51
  const oidcOptions = {
50
52
  authority: oidcLoginOptions.issuer.toString(),
51
53
  client_id: oidcLoginOptions.client.clientId,
52
54
  client_secret: oidcLoginOptions.client.clientSecret,
53
- redirect_uri: oidcLoginOptions.redirectUrl,
55
+ redirect_uri: redirectUri,
54
56
  response_type: "code",
55
57
  scope: oidcLoginOptions.scopes.join(" "),
56
58
  filterProtocolClaims: true,
@@ -58,26 +60,23 @@ export default class AuthorizationCodeWithPkceOidcHandler
58
60
  // Note that in Solid, information should be retrieved from the
59
61
  // profile referenced by the WebId.
60
62
  loadUserInfo: false,
61
- code_verifier: true,
62
63
  prompt: oidcLoginOptions.prompt ?? "consent",
63
64
  };
64
- /* eslint-enable camelcase */
65
65
 
66
66
  const oidcClientLibrary = new OidcClient(oidcOptions);
67
67
 
68
68
  try {
69
- const signingRequest = await oidcClientLibrary.createSigninRequest();
69
+ const signingRequest = await oidcClientLibrary.createSigninRequest({});
70
70
  // Make sure to await the promise before returning so that the error is caught.
71
71
  return await this.setupRedirectHandler({
72
72
  oidcLoginOptions,
73
- // eslint-disable-next-line no-underscore-dangle
74
- state: signingRequest.state._id,
75
- // eslint-disable-next-line no-underscore-dangle
76
- codeVerifier: signingRequest.state._code_verifier,
73
+
74
+ state: signingRequest.state.id,
75
+
76
+ codeVerifier: signingRequest.state.code_verifier ?? "",
77
77
  targetUrl: signingRequest.url.toString(),
78
78
  });
79
79
  } catch (err: unknown) {
80
- // eslint-disable-next-line no-console
81
80
  console.error(err);
82
81
  }
83
82
 
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -28,12 +27,12 @@ import { EVENTS } from "@inrupt/solid-client-authn-core";
28
27
  import {
29
28
  StorageUtilityMock,
30
29
  mockStorageUtility,
30
+ // eslint-disable-next-line import/no-unresolved
31
31
  } from "@inrupt/solid-client-authn-core/mocks";
32
- import type { JWK } from "jose";
32
+ import type { JWK, CryptoKey } from "jose";
33
33
  import { importJWK } from "jose";
34
34
  import type { refresh } from "@inrupt/oidc-client-ext";
35
35
  import { EventEmitter } from "events";
36
- import type { KeyObject } from "crypto";
37
36
  import TokenRefresher from "./TokenRefresher";
38
37
  import {
39
38
  mockDefaultIssuerConfigFetcher,
@@ -70,7 +69,7 @@ const mockJwk = (): JWK => {
70
69
 
71
70
  const mockKeyPair = async (): Promise<KeyPair> => {
72
71
  return {
73
- privateKey: (await importJWK(mockJwk())) as KeyObject,
72
+ privateKey: (await importJWK(mockJwk())) as CryptoKey,
74
73
  // Use the same JWK for public and private key out of convenience, don't do
75
74
  // this in real life.
76
75
  publicKey: mockJwk(),
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -42,7 +41,6 @@ import type { EventEmitter } from "events";
42
41
 
43
42
  // Some identifiers are not in camelcase on purpose, as they are named using the
44
43
  // official names from the OIDC/OAuth2 specifications.
45
- /* eslint-disable camelcase */
46
44
 
47
45
  /**
48
46
  * @hidden
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -26,7 +25,6 @@ import type {
26
25
  } from "@inrupt/solid-client-authn-core";
27
26
 
28
27
  // Some identifiers are in camelcase on purpose.
29
- /* eslint-disable camelcase */
30
28
 
31
29
  export const mockTokenRefresher = (
32
30
  tokenSet: TokenEndpointResponse,
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -18,6 +17,7 @@
18
17
  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19
18
  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
19
  //
20
+
21
21
  import type {
22
22
  IEndSessionOptions,
23
23
  IRpLogoutOptions,
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,6 +23,7 @@ import {
24
23
  StorageUtility,
25
24
  mockStorage,
26
25
  } from "@inrupt/solid-client-authn-core";
26
+ // eslint-disable-next-line import/no-unresolved
27
27
  import { mockLogoutHandler } from "@inrupt/solid-client-authn-core/mocks";
28
28
  import { jest, it, describe, expect } from "@jest/globals";
29
29
 
@@ -130,6 +130,7 @@ describe("SessionInfoManager", () => {
130
130
  refreshToken: "some refresh token",
131
131
  redirectUrl: "https://some.redirect/url",
132
132
  tokenType: "DPoP",
133
+ clientExpiresAt: undefined,
133
134
  });
134
135
  });
135
136
 
@@ -158,6 +159,7 @@ describe("SessionInfoManager", () => {
158
159
  refreshToken: undefined,
159
160
  redirectUrl: undefined,
160
161
  tokenType: "DPoP",
162
+ clientExpiresAt: undefined,
161
163
  });
162
164
  });
163
165
 
@@ -219,6 +221,65 @@ describe("SessionInfoManager", () => {
219
221
  );
220
222
  });
221
223
 
224
+ it("returns clientExpiresAt when expiresAt is in storage", async () => {
225
+ const sessionId = "commanderCool";
226
+ const expiresAt = 1700000000;
227
+
228
+ const storageMock = new StorageUtility(
229
+ mockStorage({
230
+ [`solidClientAuthenticationUser:${sessionId}`]: {
231
+ isLoggedIn: "true",
232
+ },
233
+ }),
234
+ mockStorage({
235
+ [`solidClientAuthenticationUser:${sessionId}`]: {
236
+ clientId: "https://some.app/registration",
237
+ clientSecret: "some client secret",
238
+ issuer: "https://some.issuer",
239
+ expiresAt: String(expiresAt),
240
+ },
241
+ }),
242
+ );
243
+
244
+ const sessionManager = getSessionInfoManager({
245
+ storageUtility: storageMock,
246
+ });
247
+ const session = await sessionManager.get(sessionId);
248
+ expect(session).toStrictEqual(
249
+ expect.objectContaining({
250
+ clientExpiresAt: expiresAt,
251
+ }),
252
+ );
253
+ });
254
+
255
+ it("returns undefined clientExpiresAt when expiresAt is not in storage", async () => {
256
+ const sessionId = "commanderCool";
257
+
258
+ const storageMock = new StorageUtility(
259
+ mockStorage({
260
+ [`solidClientAuthenticationUser:${sessionId}`]: {
261
+ isLoggedIn: "true",
262
+ },
263
+ }),
264
+ mockStorage({
265
+ [`solidClientAuthenticationUser:${sessionId}`]: {
266
+ clientId: "https://some.app/registration",
267
+ issuer: "https://some.issuer",
268
+ },
269
+ }),
270
+ );
271
+
272
+ const sessionManager = getSessionInfoManager({
273
+ storageUtility: storageMock,
274
+ });
275
+ const session = await sessionManager.get(sessionId);
276
+ expect(session).toStrictEqual(
277
+ expect.objectContaining({
278
+ clientExpiresAt: undefined,
279
+ }),
280
+ );
281
+ });
282
+
222
283
  it("throws if the stored token type isn't supported", async () => {
223
284
  const sessionId = "commanderCool";
224
285
 
@@ -1,4 +1,3 @@
1
- //
2
1
  // Copyright Inrupt Inc.
3
2
  //
4
3
  // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -72,6 +71,7 @@ export class SessionInfoManager
72
71
  refreshToken,
73
72
  issuer,
74
73
  tokenType,
74
+ expiresAt,
75
75
  ] = await Promise.all([
76
76
  this.storageUtility.getForUser(sessionId, "isLoggedIn", {
77
77
  secure: true,
@@ -97,6 +97,9 @@ export class SessionInfoManager
97
97
  this.storageUtility.getForUser(sessionId, "tokenType", {
98
98
  secure: false,
99
99
  }),
100
+ this.storageUtility.getForUser(sessionId, "expiresAt", {
101
+ secure: false,
102
+ }),
100
103
  ]);
101
104
 
102
105
  if (typeof redirectUrl === "string" && !isValidRedirectUrl(redirectUrl)) {
@@ -134,6 +137,8 @@ export class SessionInfoManager
134
137
  clientAppSecret: clientSecret,
135
138
  // Default the token type to DPoP if unspecified.
136
139
  tokenType: tokenType ?? "DPoP",
140
+ clientExpiresAt:
141
+ expiresAt !== undefined ? Number.parseInt(expiresAt, 10) : undefined,
137
142
  };
138
143
  }
139
144