@inrupt/solid-client-authn-browser 1.17.5 → 2.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 (45) hide show
  1. package/dist/ClientAuthentication.d.ts +1 -0
  2. package/dist/Session.d.ts +4 -67
  3. package/dist/defaultSession.d.ts +0 -28
  4. package/dist/dependencies.d.ts +1 -2
  5. package/dist/index.d.ts +2 -3
  6. package/dist/index.js +16 -124
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +9 -113
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/login/oidc/__mocks__/IOidcOptions.d.ts +2 -0
  11. package/dist/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.d.ts +4 -0
  12. package/dist/solid-client-authn.bundle.js +19 -19
  13. package/dist/solid-client-authn.bundle.js.map +1 -1
  14. package/package.json +6 -7
  15. package/rollup.config.mjs +28 -14
  16. package/src/ClientAuthentication.spec.ts +1 -12
  17. package/src/Session.spec.ts +11 -178
  18. package/src/Session.ts +6 -98
  19. package/src/defaultSession.spec.ts +0 -18
  20. package/src/defaultSession.ts +0 -40
  21. package/src/dependencies.ts +1 -2
  22. package/src/index.spec.ts +1 -2
  23. package/src/index.ts +9 -3
  24. package/src/login/oidc/ClientRegistrar.spec.ts +8 -9
  25. package/src/login/oidc/IssuerConfigFetcher.spec.ts +17 -32
  26. package/src/login/oidc/IssuerConfigFetcher.ts +1 -5
  27. package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.spec.ts +9 -29
  28. package/src/login/oidc/incomingRedirectHandler/AuthCodeRedirectHandler.ts +6 -19
  29. package/src/login/oidc/incomingRedirectHandler/ErrorOidcHandler.spec.ts +0 -11
  30. package/src/login/oidc/incomingRedirectHandler/FallbackRedirectHandler.spec.ts +1 -12
  31. package/.prettierignore +0 -3
  32. package/sampleFlows/SolidAuthClientArchitecture.png +0 -0
  33. package/sampleFlows/authorization-code-with-pkce.png +0 -0
  34. package/sampleFlows/authorization-code-with-pkce.seqdiag +0 -46
  35. package/sampleFlows/authorization-code.png +0 -0
  36. package/sampleFlows/authorization-code.seqdiag +0 -50
  37. package/sampleFlows/client-credentials.png +0 -0
  38. package/sampleFlows/client-credentials.seqdiag +0 -38
  39. package/sampleFlows/legacy-implicit-flow.png +0 -0
  40. package/sampleFlows/legacy-implicit-flow.seqdiag +0 -43
  41. package/sampleFlows/self-signed.png +0 -0
  42. package/sampleFlows/self-signed.seqdiag +0 -49
  43. package/sampleFlows/signatory-access-control.seqdiag +0 -36
  44. package/sampleFlows/signatory-access-control.svg +0 -1
  45. package/sonar-project.properties +0 -15
@@ -24,7 +24,6 @@ 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 "@inrupt/universal-fetch";
28
27
  import ClientRegistrar from "./ClientRegistrar";
29
28
  import { IssuerConfigFetcherFetchConfigResponse } from "./__mocks__/IssuerConfigFetcher";
30
29
 
@@ -47,14 +46,14 @@ describe("ClientRegistrar", () => {
47
46
  // actual OIDC provider response.
48
47
  const mockFetch = (jest.fn() as any).mockResolvedValueOnce(
49
48
  /* eslint-disable camelcase */
50
- new NodeResponse(
49
+ new Response(
51
50
  JSON.stringify({
52
51
  client_id: "abcd",
53
52
  client_secret: "1234",
54
53
  redirect_uris: ["https://example.com"],
55
54
  id_token_signed_response_alg: "RS256",
56
55
  }),
57
- ) as unknown as Response,
56
+ ),
58
57
  /* eslint-enable camelcase */
59
58
  );
60
59
  global.fetch = mockFetch;
@@ -98,12 +97,12 @@ describe("ClientRegistrar", () => {
98
97
  it("can register a public client without secret", async () => {
99
98
  const mockFetch = (jest.fn() as any).mockResolvedValueOnce(
100
99
  /* eslint-disable camelcase */
101
- new NodeResponse(
100
+ new Response(
102
101
  JSON.stringify({
103
102
  client_id: "abcd",
104
103
  redirect_uris: ["https://example.com"],
105
104
  }),
106
- ) as unknown as Response,
105
+ ),
107
106
  /* eslint-enable camelcase */
108
107
  );
109
108
  global.fetch = mockFetch;
@@ -144,9 +143,9 @@ describe("ClientRegistrar", () => {
144
143
  it("handles a failure to dynamically register elegantly", async () => {
145
144
  const mockFetch = (jest.fn() as any).mockResolvedValueOnce(
146
145
  /* eslint-disable camelcase */
147
- new NodeResponse('{"error":"bad stuff that\'s an error"}', {
146
+ new Response('{"error":"bad stuff that\'s an error"}', {
148
147
  status: 400,
149
- }) as unknown as Response,
148
+ }),
150
149
  /* eslint-enable camelcase */
151
150
  );
152
151
  global.fetch = mockFetch;
@@ -198,13 +197,13 @@ describe("ClientRegistrar", () => {
198
197
  it("saves dynamic registration information", async () => {
199
198
  const mockFetch = (jest.fn() as any).mockResolvedValueOnce(
200
199
  /* eslint-disable camelcase */
201
- new NodeResponse(
200
+ new Response(
202
201
  JSON.stringify({
203
202
  client_id: "some id",
204
203
  client_secret: "some secret",
205
204
  redirect_uris: ["https://example.com"],
206
205
  }),
207
- ) as unknown as Response,
206
+ ),
208
207
  /* eslint-enable camelcase */
209
208
  );
210
209
  global.fetch = mockFetch;
@@ -21,24 +21,22 @@
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 "@inrupt/universal-fetch";
25
- import type * as UniversalFetch from "@inrupt/universal-fetch";
26
24
  import IssuerConfigFetcher from "./IssuerConfigFetcher";
27
25
 
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 UniversalFetch)["fetch"]>(),
35
- };
36
- });
37
-
38
26
  /**
39
27
  * Test for IssuerConfigFetcher
40
28
  */
41
29
  describe("IssuerConfigFetcher", () => {
30
+ let mockFetch: jest.SpiedFunction<typeof fetch>;
31
+
32
+ beforeEach(() => {
33
+ mockFetch = jest.spyOn(globalThis, "fetch");
34
+ });
35
+
36
+ afterEach(() => {
37
+ jest.restoreAllMocks();
38
+ });
39
+
42
40
  const defaultMocks = {
43
41
  storageUtility: mockStorageUtility({}),
44
42
  };
@@ -55,11 +53,9 @@ describe("IssuerConfigFetcher", () => {
55
53
  const configFetcher = getIssuerConfigFetcher({
56
54
  storageUtility: mockStorageUtility({}),
57
55
  });
58
- const { fetch: mockFetch } = jest.requireMock(
59
- "@inrupt/universal-fetch",
60
- ) as jest.Mocked<typeof UniversalFetch>;
56
+
61
57
  mockFetch.mockResolvedValueOnce(
62
- new NodeResponse(
58
+ new Response(
63
59
  JSON.stringify({
64
60
  issuer: "https://example.com",
65
61
  // eslint-disable-next-line camelcase
@@ -83,10 +79,7 @@ describe("IssuerConfigFetcher", () => {
83
79
  });
84
80
 
85
81
  it("should throw an error if the fetched config could not be converted to JSON", async () => {
86
- const { fetch: mockFetch } = jest.requireMock(
87
- "@inrupt/universal-fetch",
88
- ) as jest.Mocked<typeof UniversalFetch>;
89
- mockFetch.mockResolvedValueOnce(new NodeResponse("Not JSON."));
82
+ mockFetch.mockResolvedValueOnce(new Response("Not JSON."));
90
83
  const configFetcher = new IssuerConfigFetcher(mockStorageUtility({}));
91
84
 
92
85
  await expect(configFetcher.fetchConfig("https://some.url")).rejects.toThrow(
@@ -95,11 +88,8 @@ describe("IssuerConfigFetcher", () => {
95
88
  });
96
89
 
97
90
  it("should return a config including the support for solid-oidc if present in the discovery profile", async () => {
98
- const { fetch: mockFetch } = jest.requireMock(
99
- "@inrupt/universal-fetch",
100
- ) as jest.Mocked<typeof UniversalFetch>;
101
91
  mockFetch.mockResolvedValueOnce(
102
- new NodeResponse(
92
+ new Response(
103
93
  JSON.stringify({
104
94
  issuer: "https://example.com",
105
95
  // eslint-disable-next-line camelcase
@@ -120,11 +110,8 @@ describe("IssuerConfigFetcher", () => {
120
110
  });
121
111
 
122
112
  it("should return a default value for the supported scopes if not advertized by the OpenID provider", async () => {
123
- const { fetch: mockFetch } = jest.requireMock(
124
- "@inrupt/universal-fetch",
125
- ) as jest.Mocked<typeof UniversalFetch>;
126
113
  mockFetch.mockResolvedValueOnce(
127
- new NodeResponse(
114
+ new Response(
128
115
  JSON.stringify({
129
116
  issuer: "https://example.com",
130
117
  // eslint-disable-next-line camelcase
@@ -143,12 +130,10 @@ describe("IssuerConfigFetcher", () => {
143
130
 
144
131
  it("should append the .well-known/openid-configuration path at the end of the issuer URL", async () => {
145
132
  // The response value is irrelevant to this test.
146
- const { fetch: mockFetch } = jest.requireMock(
147
- "@inrupt/universal-fetch",
148
- ) as jest.Mocked<typeof UniversalFetch>;
133
+
149
134
  mockFetch.mockImplementation(
150
135
  async () =>
151
- new NodeResponse(
136
+ new Response(
152
137
  JSON.stringify({
153
138
  issuer: "https://example.com",
154
139
  // eslint-disable-next-line camelcase
@@ -33,7 +33,6 @@ import type {
33
33
  IStorageUtility,
34
34
  } from "@inrupt/solid-client-authn-core";
35
35
  import { ConfigurationError } from "@inrupt/solid-client-authn-core";
36
- import { fetch as uniFetch } from "@inrupt/universal-fetch";
37
36
 
38
37
  export const WELL_KNOWN_OPENID_CONFIG = ".well-known/openid-configuration";
39
38
 
@@ -172,10 +171,7 @@ export default class IssuerConfigFetcher implements IIssuerConfigFetcher {
172
171
  // includes the full issuer path. See https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig.
173
172
  issuer.endsWith("/") ? issuer : `${issuer}/`,
174
173
  ).href;
175
- const issuerConfigRequestBody = await uniFetch.call(
176
- globalThis,
177
- openIdConfigUrl,
178
- );
174
+ const issuerConfigRequestBody = await fetch(openIdConfigUrl);
179
175
  // Check the validity of the fetched config
180
176
  try {
181
177
  issuerConfig = processConfig(await issuerConfigRequestBody.json());
@@ -35,8 +35,6 @@ import {
35
35
  import { jest, it, describe, expect } from "@jest/globals";
36
36
  import { getBearerToken } from "@inrupt/oidc-client-ext";
37
37
  import type * as OidcClientExt from "@inrupt/oidc-client-ext";
38
- import { fetch, Response, Headers } from "@inrupt/universal-fetch";
39
- import type * as UniversalFetch from "@inrupt/universal-fetch";
40
38
  import type { JWK } from "jose";
41
39
  import { importJWK } from "jose";
42
40
  import type { KeyObject } from "crypto";
@@ -48,15 +46,7 @@ import {
48
46
  mockTokenRefresher,
49
47
  } from "../refresh/__mocks__/TokenRefresher";
50
48
 
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
- });
49
+ const mockedFetch = jest.spyOn(globalThis, "fetch");
60
50
 
61
51
  const mockJwk = (): JWK => {
62
52
  return {
@@ -202,9 +192,6 @@ function mockClientRegistrar(client: IClient): IClientRegistrar {
202
192
  }
203
193
 
204
194
  const mockFetch = (response: Response) => {
205
- const { fetch: mockedFetch } = jest.requireMock(
206
- "@inrupt/universal-fetch",
207
- ) as jest.Mocked<typeof UniversalFetch>;
208
195
  mockedFetch.mockResolvedValueOnce(response);
209
196
  return mockedFetch;
210
197
  };
@@ -416,7 +403,6 @@ describe("AuthCodeRedirectHandler", () => {
416
403
 
417
404
  it("returns an authenticated bearer fetch if requested", async () => {
418
405
  mockOidcClient();
419
- const mockedFetch = jest.mocked<typeof fetch>(fetch);
420
406
  mockedFetch.mockResolvedValueOnce(
421
407
  new Response("", {
422
408
  status: 200,
@@ -427,9 +413,8 @@ describe("AuthCodeRedirectHandler", () => {
427
413
  storageUtility: mockDefaultStorageUtility({ dpop: false }),
428
414
  });
429
415
 
430
- const redirectInfo = await authCodeRedirectHandler.handle(
431
- mockRedirectUrl(),
432
- );
416
+ const redirectInfo =
417
+ await authCodeRedirectHandler.handle(mockRedirectUrl());
433
418
 
434
419
  // This will call the oidc-client-ext module, which is mocked at
435
420
  // the top of this file. The purpose of this test is to check that, if
@@ -444,7 +429,6 @@ describe("AuthCodeRedirectHandler", () => {
444
429
 
445
430
  it("returns an authenticated DPoP fetch if requested", async () => {
446
431
  mockOidcClient();
447
- const mockedFetch = jest.mocked<typeof fetch>(fetch);
448
432
  mockedFetch.mockResolvedValueOnce(
449
433
  new Response("", {
450
434
  status: 200,
@@ -454,9 +438,8 @@ describe("AuthCodeRedirectHandler", () => {
454
438
  const authCodeRedirectHandler = getAuthCodeRedirectHandler({
455
439
  storageUtility: mockDefaultStorageUtility({ dpop: true }),
456
440
  });
457
- const redirectInfo = await authCodeRedirectHandler.handle(
458
- mockRedirectUrl(),
459
- );
441
+ const redirectInfo =
442
+ await authCodeRedirectHandler.handle(mockRedirectUrl());
460
443
  await redirectInfo.fetch("https://some.other.url");
461
444
 
462
445
  const header = new Headers(mockedFetch.mock.calls[0][1]?.headers);
@@ -525,9 +508,8 @@ describe("AuthCodeRedirectHandler", () => {
525
508
  storageUtility: mockDefaultStorageUtility(),
526
509
  });
527
510
 
528
- const sessionInfo = await authCodeRedirectHandler.handle(
529
- mockRedirectUrl(),
530
- );
511
+ const sessionInfo =
512
+ await authCodeRedirectHandler.handle(mockRedirectUrl());
531
513
 
532
514
  expect(sessionInfo.expirationDate).toBe(
533
515
  MOCK_TIMESTAMP + MOCK_EXPIRE_TIME * 1000,
@@ -552,9 +534,8 @@ describe("AuthCodeRedirectHandler", () => {
552
534
  storageUtility: mockedStorage,
553
535
  });
554
536
 
555
- const sessionInfo = await authCodeRedirectHandler.handle(
556
- mockRedirectUrl(),
557
- );
537
+ const sessionInfo =
538
+ await authCodeRedirectHandler.handle(mockRedirectUrl());
558
539
 
559
540
  expect(sessionInfo.expirationDate).toBeUndefined();
560
541
  });
@@ -598,7 +579,6 @@ describe("AuthCodeRedirectHandler", () => {
598
579
  await authCodeRedirectHandler.handle(mockRedirectUrl());
599
580
 
600
581
  expect(mockAuthenticatedFetchBuild).toHaveBeenCalledWith(
601
- expect.anything(),
602
582
  expect.anything(),
603
583
  expect.objectContaining({
604
584
  refreshOptions: {
@@ -23,12 +23,6 @@
23
23
  * @hidden
24
24
  * @packageDocumentation
25
25
  */
26
- // FIXME: The following doesn't work in the browser, it results in all the fetches
27
- // being unauthenticated. This should be looked into when migrating to universal-fetch.
28
- // import { fetch } from "cross-fetch";
29
-
30
- import { fetch as uniFetch } from "@inrupt/universal-fetch";
31
-
32
26
  import type {
33
27
  IClient,
34
28
  IClientRegistrar,
@@ -49,9 +43,6 @@ import type { CodeExchangeResult } from "@inrupt/oidc-client-ext";
49
43
  import { getDpopToken, getBearerToken } from "@inrupt/oidc-client-ext";
50
44
  import type { EventEmitter } from "events";
51
45
 
52
- const globalFetch: typeof uniFetch = (...args) =>
53
- uniFetch.call(globalThis, ...args);
54
-
55
46
  /**
56
47
  * @hidden
57
48
  */
@@ -171,16 +162,12 @@ export class AuthCodeRedirectHandler implements IIncomingRedirectHandler {
171
162
  };
172
163
  }
173
164
 
174
- const authFetch = await buildAuthenticatedFetch(
175
- globalFetch,
176
- tokens.accessToken,
177
- {
178
- dpopKey: tokens.dpopKey,
179
- refreshOptions,
180
- eventEmitter,
181
- expiresIn: tokens.expiresIn,
182
- },
183
- );
165
+ const authFetch = await buildAuthenticatedFetch(tokens.accessToken, {
166
+ dpopKey: tokens.dpopKey,
167
+ refreshOptions,
168
+ eventEmitter,
169
+ expiresIn: tokens.expiresIn,
170
+ });
184
171
 
185
172
  await this.storageUtility.setForUser(
186
173
  storedSessionId,
@@ -22,19 +22,8 @@
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 type * as UniversalFetch from "@inrupt/universal-fetch";
26
25
  import { ErrorOidcHandler } from "./ErrorOidcHandler";
27
26
 
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 UniversalFetch)["fetch"]>(),
35
- };
36
- });
37
-
38
27
  describe("ErrorOidcHandler", () => {
39
28
  describe("canHandle", () => {
40
29
  it("Does not handle IRIs without an error parameter", async () => {
@@ -19,20 +19,9 @@
19
19
  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  //
21
21
 
22
- import { jest, it, describe, expect } from "@jest/globals";
23
- import type * as UniversalFetch from "@inrupt/universal-fetch";
22
+ import { it, describe, expect } from "@jest/globals";
24
23
  import { FallbackRedirectHandler } from "./FallbackRedirectHandler";
25
24
 
26
- jest.mock("@inrupt/universal-fetch", () => {
27
- const fetchModule = jest.requireActual(
28
- "@inrupt/universal-fetch",
29
- ) as typeof UniversalFetch;
30
- return {
31
- ...fetchModule,
32
- fetch: jest.fn<(typeof UniversalFetch)["fetch"]>(),
33
- };
34
- });
35
-
36
25
  describe("FallbackRedirectHandler", () => {
37
26
  describe("canHandle", () => {
38
27
  it("always accept the given IRI", async () => {
package/.prettierignore DELETED
@@ -1,3 +0,0 @@
1
- # TODO: figure out why the root .prettierignore file isn't detected:
2
- docs/**/*.md
3
- examples/**/*.md
@@ -1,46 +0,0 @@
1
- title: Authorization Code Flow with PKCE
2
-
3
- note left of RP: AUTHORIZATION
4
- note over RP: 1.Alice uses the decentphotos app
5
- note over RP: 2. Alice selets her OP or WebID
6
- RP->Alice's Pod (RS): 2.1 Retrieve Profile
7
- Alice's Pod (RS)->RP:
8
- RP->Alice's OP: 3. Requests OP configuration
9
- Alice's OP->RP: 4. Returns OP configuration
10
- RP->Alice's OP: 5. Requests OP JWKS
11
- Alice's OP->RP: 6. Returns OP JWKS
12
- note over RP: 7. Generates Private/Public key pair
13
- note over RP: 8. Generates PKCE nonce
14
- note over RP: 9. Saves both to local storage
15
- RP->Alice's OP: 10. Authorization Request
16
- Alice's OP->Decentphotos WebID: 11. Retrieves WebID
17
- Decentphotos WebID->Alice's OP:
18
- note over Alice's OP: 11. Validates redirect protocol with WebID
19
- note over Alice's OP: 12. Gets Alice's consent
20
- note over Alice's OP: 13. Generates an id_vc
21
- Alice's OP->RP: 12. Sends code to redirect protocol
22
- RP->Alice's OP: 13. Token requst with code and nonce proof
23
- note over Alice's OP: 14. Validates nonce proof
24
- Alice's OP->RP: 15. Sends id_vc inside id_token
25
-
26
-
27
- note left of RP: SENDING REQUEST
28
- note over RP: 1. Creates a pop_token
29
- RP->Bob's Pod (RS): 2. Request sent
30
- note over Bob's Pod (RS): 3. Checks pop_token Audience
31
- note over Bob's Pod (RS): 4. Checks client signature
32
- Bob's Pod (RS)->Alice's Pod (RS): 5. Retrieves Profile
33
- Alice's Pod (RS)->Bob's Pod (RS):
34
- note over Bob's Pod (RS): 6. Checks Issuer
35
- Bob's Pod (RS)->Alice's OP: 7. Retrieves OP configuration
36
- Alice's OP->Bob's Pod (RS):
37
- Bob's Pod (RS)->Alice's OP: 8. Requests JWKS
38
- Alice's OP->Bob's Pod (RS):
39
- note over Bob's Pod (RS): 9. Performs Authentication
40
- note over Bob's Pod (RS): 10. Performs Authorization
41
- Bob's Pod (RS)->RP: 11. Returns Result
42
-
43
- note left of RP: REFRESH TOKEN
44
- Bob's Pod (RS)->RP: 1. 401: token expired
45
- RP->Alice's OP: 2. Refresh token auth request
46
- Alice's OP->RP: 3. Return updated token
Binary file
@@ -1,50 +0,0 @@
1
- title: Authorization Code Grant
2
-
3
- note left of Alice's Browser: Authorization
4
- note over Decentphotos Server: 1. Has a public/private keypair
5
- note over Decentphotos WebID: 1. Has pub key cert
6
- note over Alice's Browser: 2. Alice navigates to decentphotos.example
7
- Alice's Browser->Decentphotos Server: 3. Retrieves webpage with session
8
- Decentphotos Server->Alice's Browser:
9
- note over Alice's Browser: 4. Alice selets her OP or WebID
10
- Alice's Browser->Decentphotos Server: 5. Requests login with OP / WebID
11
- Decentphotos Server->Alice's Pod (RS): 5.1 Retrieve Profile
12
- Alice's Pod (RS)->Decentphotos Server:
13
- Decentphotos Server->Alice's OP: 6. Requests OP configuration
14
- Alice's OP->Decentphotos Server:
15
- Decentphotos Server->Alice's OP: 7. Requests OP JWKS
16
- Alice's OP->Decentphotos Server:
17
- Decentphotos Server->Alice's Browser: 8. Redirects to Auth endpoint
18
- Alice's Browser->Alice's OP: 9. Authorization Request
19
- note over Alice's OP: 10. Gets Alice's consent
20
- Alice's OP->Alice's Browser: 11. Returns to redirect_url with access_code
21
- Alice's Browser-> Decentphotos Server: 12. Transfers Access Code
22
- Decentphotos Server->Alice's OP: 13. Auth request with proof of private key
23
- Alice's OP->Decentphotos WebID: 14. Retrieves app WebID
24
- Decentphotos WebID->Alice's OP:
25
- note over Alice's OP: 15. Validates cert with WebID
26
- note over Alice's OP: 16. Generates an access_code
27
- Alice's OP->Decentphotos Server: 17. Returns access_code and refresh_token
28
-
29
- note left of Alice's Browser: SENDING REQUEST
30
- Alice's Browser->Decentphotos Server: 1. Sends Request details
31
- note over Decentphotos Server: 2. Creates a pop_token
32
- Decentphotos Server->Bob's Pod (RS): 3. Request sent
33
- note over Bob's Pod (RS): 4. Checks pop_token Audience
34
- note over Bob's Pod (RS): 5. Checks client signature
35
- Bob's Pod (RS)->Alice's Pod (RS): 6. Retrieves Profile
36
- Alice's Pod (RS)->Bob's Pod (RS):
37
- note over Bob's Pod (RS): 7. Checks Issuer
38
- Bob's Pod (RS)->Alice's OP: 8. Retrieves OP configuration
39
- Alice's OP->Bob's Pod (RS):
40
- Bob's Pod (RS)->Alice's OP: 9. Requests JWKS
41
- Alice's OP->Bob's Pod (RS):
42
- note over Bob's Pod (RS): 10. Performs Authentication
43
- note over Bob's Pod (RS): 11. Performs Authorization
44
- Bob's Pod (RS)->Decentphotos Server: 12. Returns Result
45
- Decentphotos Server->Alice's Browser: 13. Returns result
46
-
47
- note left of Alice's Browser: REFRESH pop_token
48
- Bob's Pod (RS)->Decentphotos Server: 1. 401: token expired
49
- Decentphotos Server->Alice's OP: 2. Refresh token auth request
50
- Alice's OP->Decentphotos Server: 3. Return updated token
Binary file
@@ -1,38 +0,0 @@
1
- title: Client Credentials Grant
2
-
3
- note left of RP: AUTHORIZATION
4
- note over RP: 1. Alice's server knows a client_secret and OP
5
- RP->Alice's OP: 2. Requests OP configuration
6
- Alice's OP->RP: 3. Returns OP configuration
7
- RP->Alice's OP: 4. Requests OP JWKS
8
- Alice's OP->RP: 5. Returns OP JWKS
9
- note over RP: 6. Generates Private/Public key pair
10
- note over RP: 7. Saves Private/Public key pair to local storage
11
- RP->Alice's OP: 8. Authorization Request
12
- Alice's OP->RP WebID: 9. Retrieves WebID
13
- RP WebID->Alice's OP:
14
- note over Alice's OP: 10. Validates redirect_url with WebID
15
- note over Alice's OP: 11. Validate Client Secret
16
- note over Alice's OP: 12. Generates an access_token
17
- Alice's OP->RP: 12. Returns to redirect_url
18
-
19
- note left of RP: SENDING REQUEST
20
- note over RP: 1. Creates a pop_token
21
- RP->Bob's Pod (RS): 2. Request sent
22
- note over Bob's Pod (RS): 3. Checks pop_token Audience
23
- note over Bob's Pod (RS): 4. Checks client signature
24
- Bob's Pod (RS)->Alice's Pod (RS): 5. Retrieves Profile
25
- Alice's Pod (RS)->Bob's Pod (RS):
26
- note over Bob's Pod (RS): 6. Checks Issuer
27
- Bob's Pod (RS)->Alice's OP: 7. Retrieves OP configuration
28
- Alice's OP->Bob's Pod (RS):
29
- Bob's Pod (RS)->Alice's OP: 8. Requests JWKS
30
- Alice's OP->Bob's Pod (RS):
31
- note over Bob's Pod (RS): 9. Performs Authentication
32
- note over Bob's Pod (RS): 10. Performs Authorization
33
- Bob's Pod (RS)->RP: 11. Returns Result
34
-
35
- note left of RP: REFRESH TOKEN
36
- Bob's Pod (RS)->RP: 1. 401: token expired
37
- RP->Alice's OP: 2. Refresh token auth request
38
- Alice's OP->RP: 3. Return updated token
@@ -1,43 +0,0 @@
1
- title: Legacy Implicit Flow
2
-
3
- note left of RP: AUTHORIZATION
4
- note over RP: 1. Alice navigates to decentphotos.example
5
- note over RP: 2. Alice selets her OP or WebID
6
- RP->Alice's Pod (RS): 2.1 Retrieve Profile
7
- Alice's Pod (RS)->RP:
8
- RP->Alice's OP: 3. Requests OP configuration
9
- Alice's OP->RP: 4. Returns OP configuration
10
- RP->Alice's OP: 5. Requests OP JWKS
11
- Alice's OP->RP: 6. Returns OP JWKS
12
- note over RP: 7. Generates Private/Public key pair
13
- note over RP: 8. Saves Private/Public key pair to local storage
14
- RP->Alice's OP: 9. Authorization Request
15
- Alice's OP->Decentphotos WebID: 10. Retrieves WebID
16
- Decentphotos WebID->Alice's OP:
17
- note over Alice's OP: 11. Validates redirect_url with WebID
18
- note over Alice's OP: 12. Gets Alice's consent
19
- note over Alice's OP: 13. Generates an access_token
20
- Alice's OP->RP: 12. Returns to redirect_url
21
-
22
- note left of RP: SENDING REQUEST
23
- note over RP: 1. Creates a pop_token
24
- RP->Bob's Pod (RS): 2. Request sent
25
- note over Bob's Pod (RS): 3. Checks pop_token Audience
26
- note over Bob's Pod (RS): 4. Checks client signature
27
- Bob's Pod (RS)->Alice's Pod (RS): 5. Retrieves Profile
28
- Alice's Pod (RS)->Bob's Pod (RS):
29
- note over Bob's Pod (RS): 6. Checks Issuer
30
- Bob's Pod (RS)->Alice's OP: 7. Retrieves OP configuration
31
- Alice's OP->Bob's Pod (RS):
32
- Bob's Pod (RS)->Alice's OP: 8. Requests JWKS
33
- Alice's OP->Bob's Pod (RS):
34
- note over Bob's Pod (RS): 9. Performs Authentication
35
- note over Bob's Pod (RS): 10. Performs Authorization
36
- Bob's Pod (RS)->RP: 11. Returns Result
37
-
38
- note left of RP: SILENT REFRESH
39
- Bob's Pod (RS)->RP: 1. 401: token expired
40
- note over RP: 2. Opens iFrame to OP
41
- RP->Alice's OP: 3. Authorization Request with prompt=none
42
- Alice's OP->RP: 4. Return updated token
43
-
Binary file
@@ -1,49 +0,0 @@
1
- title: Self Issued Flow
2
-
3
- note left of RP: AUTHENTICATION
4
- note over RP: 1. Alice uses the Decentphotos App
5
- note over OP: 2. Alice has a self-signed app installed
6
- note over OP: It knows Alice's private key
7
- note over Alice's WebID: 3. issuer: selfissued.me
8
- note over Alice's WebID: Knows Alice's pub cert
9
- note over RP: 4. Alice selects her OP or WebID
10
- RP->Alice's WebID: 4.1 Gets WebID
11
- Alice's WebID->RP:
12
- RP->OP: 5. Requests OP configuration
13
- OP->RP:
14
- RP->OP: 6. Requests OP JWKS
15
- OP->RP:
16
- note over RP: 7. Generates Private/Public key pair
17
- note over RP: 8. Generates PKCE nonce
18
- note over RP: 9. Saves both to local storage
19
- RP->OP: 10. Authorization Request
20
- OP->Decentphotos WebID: 11. Retrieves WebID
21
- Decentphotos WebID->OP:
22
- note over OP: 11. Validates redirect protocol with WebID
23
- note over OP: 12. Gets Alice's consent
24
- note over OP: 13. Generates an access_code
25
- OP->RP: 12. Sends code to redirect protocol
26
- RP->OP: 13. Token requst with code and nonce proof
27
- note over OP: 14. Validates nonce proof
28
- OP->RP: 15. Sends access_token
29
-
30
- note left of RP: SENDING REQUEST
31
- note over RP: 1. Creates a pop_token
32
- RP->Bob's Pod (RS): 2. Request sent
33
- note over Bob's Pod (RS): 3. Checks pop_token Audience
34
- note over Bob's Pod (RS): 4. Checks client signature
35
- Bob's Pod (RS)->Alice's WebID: 5. Retrieves Profile
36
- Alice's WebID->Bob's Pod (RS):
37
- note over Bob's Pod (RS): 6. Checks that access_token cert matches WebID
38
- Bob's Pod (RS)->OP: 7. Retrieves OP configuration
39
- OP->Bob's Pod (RS):
40
- Bob's Pod (RS)->OP: 8. Requests JWKS
41
- OP->Bob's Pod (RS):
42
- note over Bob's Pod (RS): 9. Performs Authentication
43
- note over Bob's Pod (RS): 10. Performs Authorization
44
- Bob's Pod (RS)->RP: 11. Returns Result
45
-
46
- note left of RP: REFRESH TOKEN
47
- Bob's Pod (RS)->RP: 1. 401: token expired
48
- RP->OP: 2. Refresh token auth request
49
- OP->RP: 3. Return updated token
@@ -1,36 +0,0 @@
1
- title: Legacy Implicit Flow
2
-
3
- note left of RP: AUTHORIZATION
4
- note over RP: 1. Alice navigates to badguys.com
5
- note over RP: 2. Alice selects her OP or WebID
6
- RP->Alice's WebId: 2.1 Retrieve Profile
7
- Alice's WebId->RP:
8
- RP->Alice's OP: 3. Get OP configuration
9
- Alice's OP->RP:
10
- RP->Alice's OP: 4. Get OP JWKS
11
- Alice's OP->RP:
12
- note over RP: 5. Generates Private/Public key pair
13
- note over RP: 6. Saves Private/Public key pair to local storage
14
- RP->Alice's OP: 7. Authorization Request
15
- Alice's OP->badguys.com WebId: 8. Retrieves WebID
16
- badguys.com WebId->Alice's OP:
17
- note over Alice's OP: 9. Validates redirect_url with WebID
18
- note over Alice's OP: 10. Gets Alice's consent
19
- note over Alice's OP: 11. Generates an access_token
20
- Alice's OP->RP: 12. Returns to redirect_url
21
-
22
- note left of RP: SENDING REQUEST
23
- note over RP: 1. Creates a pop_token
24
- RP->Bob's Pod (RS): 2. Request sent
25
- note over Bob's Pod (RS): 3. Checks pop_token Audience
26
- note over Bob's Pod (RS): 4. Checks client signature
27
- Bob's Pod (RS)->Alice's WebId: 5. Retrieves Subject Profile
28
- Alice's WebId->Bob's Pod (RS):
29
- note over Bob's Pod (RS): 6. Checks Issuer
30
- Bob's Pod (RS)->Alice's OP: 7. Retrieves OP configuration
31
- Alice's OP->Bob's Pod (RS):
32
- Bob's Pod (RS)->Alice's OP: 8. Requests JWKS
33
- Alice's OP->Bob's Pod (RS):
34
- note over Bob's Pod (RS): 9. Performs Authentication
35
- note over Bob's Pod (RS): 10. Performs Authorization
36
- Bob's Pod (RS)->RP: 11. Returns Result