oidc-spa 8.6.19 → 8.7.1

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 (140) hide show
  1. package/backend.d.ts +3 -20
  2. package/backend.js +50 -242
  3. package/backend.js.map +1 -1
  4. package/core/OidcMetadata.d.ts +2 -2
  5. package/core/OidcMetadata.js.map +1 -1
  6. package/core/createOidc.d.ts +2 -4
  7. package/core/createOidc.js +49 -3
  8. package/core/createOidc.js.map +1 -1
  9. package/core/dpop.d.ts +20 -0
  10. package/core/dpop.js +389 -0
  11. package/core/dpop.js.map +1 -0
  12. package/core/earlyInit.js +2 -0
  13. package/core/earlyInit.js.map +1 -1
  14. package/core/oidcClientTsUserToTokens.d.ts +1 -0
  15. package/core/oidcClientTsUserToTokens.js +15 -5
  16. package/core/oidcClientTsUserToTokens.js.map +1 -1
  17. package/core/tokenExfiltrationDefense.js +49 -6
  18. package/core/tokenExfiltrationDefense.js.map +1 -1
  19. package/esm/angular.d.ts +2 -0
  20. package/esm/angular.mjs.map +1 -1
  21. package/esm/backend.d.ts +3 -20
  22. package/esm/backend.mjs +50 -242
  23. package/esm/backend.mjs.map +1 -1
  24. package/esm/core/OidcMetadata.d.ts +2 -2
  25. package/esm/core/OidcMetadata.mjs.map +1 -1
  26. package/esm/core/createOidc.d.ts +2 -4
  27. package/esm/core/createOidc.mjs +49 -3
  28. package/esm/core/createOidc.mjs.map +1 -1
  29. package/esm/core/dpop.d.ts +20 -0
  30. package/esm/core/dpop.mjs +384 -0
  31. package/esm/core/dpop.mjs.map +1 -0
  32. package/esm/core/earlyInit.mjs +2 -0
  33. package/esm/core/earlyInit.mjs.map +1 -1
  34. package/esm/core/oidcClientTsUserToTokens.d.ts +1 -0
  35. package/esm/core/oidcClientTsUserToTokens.mjs +15 -5
  36. package/esm/core/oidcClientTsUserToTokens.mjs.map +1 -1
  37. package/esm/core/tokenExfiltrationDefense.mjs +49 -6
  38. package/esm/core/tokenExfiltrationDefense.mjs.map +1 -1
  39. package/esm/react-spa/createOidcSpaApi.mjs +2 -1
  40. package/esm/react-spa/createOidcSpaApi.mjs.map +1 -1
  41. package/esm/react-spa/types.d.ts +2 -0
  42. package/esm/server/createOidcSpaUtils.d.ts +5 -0
  43. package/esm/server/createOidcSpaUtils.mjs +639 -0
  44. package/esm/server/createOidcSpaUtils.mjs.map +1 -0
  45. package/esm/server/index.d.ts +2 -0
  46. package/esm/server/index.mjs +3 -0
  47. package/esm/server/index.mjs.map +1 -0
  48. package/esm/server/types.d.ts +79 -0
  49. package/esm/server/types.mjs +2 -0
  50. package/esm/server/types.mjs.map +1 -0
  51. package/esm/server/utilsBuilder.d.ts +10 -0
  52. package/esm/server/utilsBuilder.mjs +13 -0
  53. package/esm/server/utilsBuilder.mjs.map +1 -0
  54. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.d.ts +1 -1
  55. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.mjs +102 -94
  56. package/esm/tanstack-start/react/accessTokenValidation_rfc9068.mjs.map +1 -1
  57. package/esm/tanstack-start/react/createOidcSpaApi.d.ts +2 -2
  58. package/esm/tanstack-start/react/createOidcSpaApi.mjs +60 -51
  59. package/esm/tanstack-start/react/createOidcSpaApi.mjs.map +1 -1
  60. package/esm/tanstack-start/react/index.d.ts +1 -1
  61. package/esm/tanstack-start/react/index.mjs +2 -2
  62. package/esm/tanstack-start/react/index.mjs.map +1 -1
  63. package/esm/tanstack-start/react/types.d.ts +36 -11
  64. package/esm/tanstack-start/react/{apiBuilder.d.ts → utilsBuilder.d.ts} +9 -9
  65. package/esm/tanstack-start/react/{apiBuilder.mjs → utilsBuilder.mjs} +6 -6
  66. package/esm/tanstack-start/react/utilsBuilder.mjs.map +1 -0
  67. package/esm/tools/generateES256DPoPProof.d.ts +8 -0
  68. package/esm/tools/generateES256DPoPProof.mjs +48 -0
  69. package/esm/tools/generateES256DPoPProof.mjs.map +1 -0
  70. package/esm/tools/getServerDateNow.d.ts +5 -0
  71. package/esm/tools/getServerDateNow.mjs +7 -0
  72. package/esm/tools/getServerDateNow.mjs.map +1 -0
  73. package/esm/vendor/{backend → server}/evt.mjs +84 -140
  74. package/esm/vendor/{backend → server}/jose.mjs +5 -27
  75. package/esm/vendor/{backend → server}/tsafe.d.ts +1 -0
  76. package/esm/vendor/{backend → server}/tsafe.mjs +6 -0
  77. package/esm/vendor/{backend → server}/zod.mjs +196 -50
  78. package/package.json +6 -1
  79. package/react-spa/createOidcSpaApi.js +2 -1
  80. package/react-spa/createOidcSpaApi.js.map +1 -1
  81. package/react-spa/types.d.ts +2 -0
  82. package/server/createOidcSpaUtils.d.ts +5 -0
  83. package/server/createOidcSpaUtils.js +642 -0
  84. package/server/createOidcSpaUtils.js.map +1 -0
  85. package/server/index.d.ts +2 -0
  86. package/server/index.js +6 -0
  87. package/server/index.js.map +1 -0
  88. package/server/types.d.ts +79 -0
  89. package/server/types.js +3 -0
  90. package/server/types.js.map +1 -0
  91. package/server/utilsBuilder.d.ts +10 -0
  92. package/server/utilsBuilder.js +16 -0
  93. package/server/utilsBuilder.js.map +1 -0
  94. package/src/angular.ts +3 -0
  95. package/src/backend.ts +63 -364
  96. package/src/core/OidcMetadata.ts +4 -2
  97. package/src/core/createOidc.ts +62 -6
  98. package/src/core/dpop.ts +583 -0
  99. package/src/core/earlyInit.ts +3 -0
  100. package/src/core/oidcClientTsUserToTokens.ts +18 -4
  101. package/src/core/tokenExfiltrationDefense.ts +60 -5
  102. package/src/react-spa/createOidcSpaApi.ts +2 -1
  103. package/src/react-spa/types.tsx +3 -0
  104. package/src/server/createOidcSpaUtils.ts +848 -0
  105. package/src/server/index.ts +4 -0
  106. package/src/server/types.tsx +99 -0
  107. package/src/server/utilsBuilder.ts +41 -0
  108. package/src/tanstack-start/react/accessTokenValidation_rfc9068.ts +134 -124
  109. package/src/tanstack-start/react/createOidcSpaApi.ts +73 -69
  110. package/src/tanstack-start/react/index.ts +2 -2
  111. package/src/tanstack-start/react/types.tsx +44 -12
  112. package/src/tanstack-start/react/{apiBuilder.ts → utilsBuilder.ts} +14 -14
  113. package/src/tools/generateES256DPoPProof.ts +74 -0
  114. package/src/tools/getServerDateNow.ts +11 -0
  115. package/src/vendor/{backend → server}/tsafe.ts +1 -0
  116. package/tools/generateES256DPoPProof.d.ts +8 -0
  117. package/tools/generateES256DPoPProof.js +51 -0
  118. package/tools/generateES256DPoPProof.js.map +1 -0
  119. package/tools/getServerDateNow.d.ts +5 -0
  120. package/tools/getServerDateNow.js +10 -0
  121. package/tools/getServerDateNow.js.map +1 -0
  122. package/vendor/server/evt.js +3 -0
  123. package/vendor/server/jose.js +3 -0
  124. package/vendor/{backend → server}/tsafe.d.ts +1 -0
  125. package/vendor/server/tsafe.js +2 -0
  126. package/vendor/server/zod.js +3 -0
  127. package/esm/tanstack-start/react/apiBuilder.mjs.map +0 -1
  128. package/vendor/backend/evt.js +0 -3
  129. package/vendor/backend/jose.js +0 -3
  130. package/vendor/backend/tsafe.js +0 -2
  131. package/vendor/backend/zod.js +0 -3
  132. /package/esm/vendor/{backend → server}/evt.d.ts +0 -0
  133. /package/esm/vendor/{backend → server}/jose.d.ts +0 -0
  134. /package/esm/vendor/{backend → server}/zod.d.ts +0 -0
  135. /package/src/vendor/{backend → server}/evt.ts +0 -0
  136. /package/src/vendor/{backend → server}/jose.ts +0 -0
  137. /package/src/vendor/{backend → server}/zod.ts +0 -0
  138. /package/vendor/{backend → server}/evt.d.ts +0 -0
  139. /package/vendor/{backend → server}/jose.d.ts +0 -0
  140. /package/vendor/{backend → server}/zod.d.ts +0 -0
@@ -0,0 +1,3 @@
1
+ import { oidcSpaUtilsBuilder } from "./utilsBuilder.mjs";
2
+ export const oidcSpa = oidcSpaUtilsBuilder;
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,CAAC,MAAM,OAAO,GAAG,mBAAmB,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Claims defined by RFC 9068: "JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens"
3
+ * https://datatracker.ietf.org/doc/html/rfc9068
4
+ *
5
+ * These tokens are intended for consumption by resource servers.
6
+ */
7
+ export type DecodedAccessToken_RFC9068 = {
8
+ iss: string;
9
+ sub: string;
10
+ aud: string | string[];
11
+ exp: number;
12
+ iat: number;
13
+ client_id?: string;
14
+ scope?: string;
15
+ jti?: string;
16
+ nbf?: number;
17
+ auth_time?: number;
18
+ cnf?: Record<string, unknown>;
19
+ [key: string]: unknown;
20
+ };
21
+ export type ValidateAndDecodeAccessToken<DecodedAccessToken> = (params: {
22
+ request: {
23
+ method: string;
24
+ url: string;
25
+ headers: Record<"Authorization" | "DPoP", string | null | undefined>;
26
+ };
27
+ }) => Promise<ValidateAndDecodeAccessToken.ReturnType<DecodedAccessToken>>;
28
+ export declare namespace ValidateAndDecodeAccessToken {
29
+ type ReturnType<DecodedAccessToken> = (ReturnType.Success<DecodedAccessToken> & {
30
+ errorCause?: never;
31
+ debugErrorMessage?: never;
32
+ }) | (ReturnType.Errored & {
33
+ decodedAccessToken?: never;
34
+ decodedAccessToken_original?: never;
35
+ accessToken?: never;
36
+ });
37
+ namespace ReturnType {
38
+ type Success<DecodedAccessToken> = {
39
+ isSuccess: true;
40
+ decodedAccessToken: DecodedAccessToken;
41
+ decodedAccessToken_original: DecodedAccessToken_RFC9068;
42
+ accessToken: string;
43
+ };
44
+ type Errored = {
45
+ isSuccess: false;
46
+ errorCause: "missing Authorization header" | "validation error" | "validation error - access token expired" | "validation error - invalid signature";
47
+ debugErrorMessage: string;
48
+ };
49
+ }
50
+ }
51
+ export type ParamsOfBootstrap<DecodedAccessToken> = ParamsOfBootstrap.Real | ParamsOfBootstrap.Mock<DecodedAccessToken>;
52
+ export declare namespace ParamsOfBootstrap {
53
+ type Real = {
54
+ implementation: "real";
55
+ issuerUri: string;
56
+ expectedAudience: string | undefined;
57
+ };
58
+ type Mock<DecodedAccessToken> = Mock.DecodeOnly | Mock.UseStaticIdentity<DecodedAccessToken>;
59
+ namespace Mock {
60
+ type Common = {
61
+ implementation: "mock";
62
+ };
63
+ export type DecodeOnly = Common & {
64
+ behavior: "decode only";
65
+ };
66
+ export type UseStaticIdentity<DecodedAccessToken> = Common & {
67
+ behavior: "use static identity";
68
+ decodedAccessToken_mock: DecodedAccessToken;
69
+ decodedAccessToken_original_mock?: DecodedAccessToken_RFC9068;
70
+ accessToken_mock?: string;
71
+ };
72
+ export {};
73
+ }
74
+ }
75
+ export type OidcSpaUtils<DecodedAccessToken> = {
76
+ bootstrapAuth: (params: ParamsOfBootstrap<DecodedAccessToken>) => Promise<void>;
77
+ validateAndDecodeAccessToken: ValidateAndDecodeAccessToken<DecodedAccessToken>;
78
+ ofTypeDecodedAccessToken: DecodedAccessToken;
79
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.mjs","sourceRoot":"","sources":["../../src/server/types.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import type { OidcSpaUtils } from "./types";
2
+ import type { ZodSchemaLike } from "../tools/ZodSchemaLike";
3
+ import type { DecodedAccessToken_RFC9068 } from "./types";
4
+ export type OidcSpaUtilsBuilder<DecodedAccessToken extends Record<string, unknown> = DecodedAccessToken_RFC9068, ExcludedMethod extends "withExpectedDecodedAccessTokenShape" | "createUtils" = never> = Omit<{
5
+ withExpectedDecodedAccessTokenShape: <DecodedAccessToken extends Record<string, unknown>>(params: {
6
+ decodedAccessTokenSchema: ZodSchemaLike<DecodedAccessToken_RFC9068, DecodedAccessToken>;
7
+ }) => OidcSpaUtilsBuilder<DecodedAccessToken, ExcludedMethod | "withExpectedDecodedAccessTokenShape">;
8
+ createUtils: () => OidcSpaUtils<DecodedAccessToken>;
9
+ }, ExcludedMethod>;
10
+ export declare const oidcSpaUtilsBuilder: OidcSpaUtilsBuilder<DecodedAccessToken_RFC9068, never>;
@@ -0,0 +1,13 @@
1
+ import { createOidcSpaUtils } from "./createOidcSpaUtils.mjs";
2
+ function createOidcSpaUtilsBuilder(params) {
3
+ return {
4
+ withExpectedDecodedAccessTokenShape: ({ decodedAccessTokenSchema }) => createOidcSpaUtilsBuilder({ decodedAccessTokenSchema }),
5
+ createUtils: () => createOidcSpaUtils({
6
+ decodedAccessTokenSchema: params.decodedAccessTokenSchema
7
+ })
8
+ };
9
+ }
10
+ export const oidcSpaUtilsBuilder = createOidcSpaUtilsBuilder({
11
+ decodedAccessTokenSchema: undefined
12
+ });
13
+ //# sourceMappingURL=utilsBuilder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utilsBuilder.mjs","sourceRoot":"","sources":["../../src/server/utilsBuilder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAqB1D,SAAS,yBAAyB,CAEhC,MAED;IACG,OAAO;QACH,mCAAmC,EAAE,CAAC,EAAE,wBAAwB,EAAE,EAAE,EAAE,CAClE,yBAAyB,CAAC,EAAE,wBAAwB,EAAE,CAAC;QAC3D,WAAW,EAAE,GAAG,EAAE,CACd,kBAAkB,CAAqB;YACnC,wBAAwB,EAAE,MAAM,CAAC,wBAAwB;SAC5D,CAAC;KACT,CAAC;AACN,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;IACzD,wBAAwB,EAAE,SAAS;CACtC,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { CreateValidateAndGetAccessTokenClaims, ParamsOfBootstrap } from "./types";
2
- import type { DecodedAccessToken_RFC9068 as AccessTokenClaims_RFC9068 } from "../../backend";
2
+ import type { DecodedAccessToken_RFC9068 as AccessTokenClaims_RFC9068 } from "../../server/types";
3
3
  import type { ZodSchemaLike } from "../../tools/ZodSchemaLike";
4
4
  export declare function createCreateValidateAndGetAccessTokenClaims_rfc9068<AccessTokenClaims extends Record<string, unknown>>(params: {
5
5
  accessTokenClaimsSchema?: ZodSchemaLike<AccessTokenClaims_RFC9068, AccessTokenClaims>;
@@ -1,14 +1,67 @@
1
1
  import { createObjectThatThrowsIfAccessed } from "../../tools/createObjectThatThrowsIfAccessed.mjs";
2
- import { assert, is } from "../../tools/tsafe/assert.mjs";
2
+ import { assert, is, id } from "../../vendor/server/tsafe.mjs";
3
3
  export function createCreateValidateAndGetAccessTokenClaims_rfc9068(params) {
4
4
  const { accessTokenClaimsSchema, accessTokenClaims_mock, expectedAudience: expectedAudienceGetter } = params;
5
5
  const createValidateAndGetAccessTokenClaims = ({ paramsOfBootstrap }) => {
6
- if (paramsOfBootstrap.implementation === "mock") {
7
- return {
8
- validateAndGetAccessTokenClaims: async () => {
9
- return {
10
- isValid: true,
11
- accessTokenClaims: (() => {
6
+ const prValidateAndDecodeAccessToken = (async () => {
7
+ const { oidcSpa: oidcSpa_server } = await import("../../server/index.mjs");
8
+ const { bootstrapAuth, validateAndDecodeAccessToken } = accessTokenClaimsSchema === undefined
9
+ ? oidcSpa_server.createUtils()
10
+ : oidcSpa_server
11
+ .withExpectedDecodedAccessTokenShape({
12
+ decodedAccessTokenSchema: accessTokenClaimsSchema
13
+ })
14
+ .createUtils();
15
+ switch (paramsOfBootstrap.implementation) {
16
+ case "real":
17
+ {
18
+ const expectedAudience = (() => {
19
+ if (expectedAudienceGetter === undefined) {
20
+ return undefined;
21
+ }
22
+ const missingEnvNames = new Set();
23
+ const env_proxy = new Proxy({}, {
24
+ get: (...[, envName]) => {
25
+ assert(typeof envName === "string");
26
+ const value = process.env[envName];
27
+ if (value === undefined) {
28
+ missingEnvNames.add(envName);
29
+ return "";
30
+ }
31
+ return value;
32
+ },
33
+ has: (...[, envName]) => {
34
+ assert(typeof envName === "string");
35
+ return true;
36
+ }
37
+ });
38
+ const expectedAudience = expectedAudienceGetter?.({
39
+ paramsOfBootstrap,
40
+ process: { env: env_proxy }
41
+ });
42
+ if (!expectedAudience) {
43
+ throw new Error([
44
+ "oidc-spa: The expectedAudience() you provided returned empty.",
45
+ "If you specified the expectedAudience in withAccessTokenValidation",
46
+ "it's probably an error.",
47
+ missingEnvNames.size !== 0 &&
48
+ `Did you forget to set the env var: ${Array.from(missingEnvNames).join(", ")} ?`
49
+ ]
50
+ .filter(line => typeof line === "string")
51
+ .join(" "));
52
+ }
53
+ return expectedAudience;
54
+ })();
55
+ await bootstrapAuth({
56
+ implementation: "real",
57
+ issuerUri: paramsOfBootstrap.issuerUri,
58
+ expectedAudience
59
+ });
60
+ }
61
+ break;
62
+ case "mock":
63
+ {
64
+ const decodedAccessToken_mock = (() => {
12
65
  if (paramsOfBootstrap.accessTokenClaims_mock !== undefined) {
13
66
  assert(is(paramsOfBootstrap.accessTokenClaims_mock));
14
67
  return paramsOfBootstrap.accessTokenClaims_mock;
@@ -24,99 +77,54 @@ export function createCreateValidateAndGetAccessTokenClaims_rfc9068(params) {
24
77
  "specify accessTokenClaims_mock when calling bootstrapOidc()"
25
78
  ].join(" ")
26
79
  });
27
- })()
28
- };
29
- }
30
- };
31
- }
32
- assert;
33
- const prVerifyAndDecodeAccessToken = (async () => {
34
- const { createOidcBackend } = await import("../../backend.mjs");
35
- const { verifyAndDecodeAccessToken } = await createOidcBackend({
36
- issuerUri: paramsOfBootstrap.issuerUri,
37
- decodedAccessTokenSchema: accessTokenClaimsSchema
38
- });
39
- return verifyAndDecodeAccessToken;
40
- })();
41
- const expectedAudience = (() => {
42
- if (expectedAudienceGetter === undefined) {
43
- return undefined;
44
- }
45
- const missingEnvNames = new Set();
46
- const env_proxy = new Proxy({}, {
47
- get: (...[, envName]) => {
48
- assert(typeof envName === "string");
49
- const value = process.env[envName];
50
- if (value === undefined) {
51
- missingEnvNames.add(envName);
52
- return "";
80
+ })();
81
+ await bootstrapAuth({
82
+ implementation: "mock",
83
+ behavior: "use static identity",
84
+ decodedAccessToken_mock
85
+ });
53
86
  }
54
- return value;
55
- },
56
- has: (...[, envName]) => {
57
- assert(typeof envName === "string");
58
- return true;
59
- }
60
- });
61
- const expectedAudience = expectedAudienceGetter?.({
62
- paramsOfBootstrap,
63
- process: { env: env_proxy }
64
- });
65
- if (!expectedAudience) {
66
- throw new Error([
67
- "oidc-spa: The expectedAudience() you provided returned empty.",
68
- "If you specified the expectedAudience in withAccessTokenValidation",
69
- "it's probably and error.",
70
- missingEnvNames.size !== 0 &&
71
- `Did you forget to set the env var: ${Array.from(missingEnvNames).join(", ")} ?`
72
- ]
73
- .filter(line => typeof line === "string")
74
- .join(" "));
87
+ break;
88
+ default:
89
+ assert(false);
75
90
  }
76
- return expectedAudience;
91
+ return validateAndDecodeAccessToken;
77
92
  })();
78
- return {
79
- validateAndGetAccessTokenClaims: async ({ accessToken }) => {
80
- const verifyAndDecodeAccessToken = await prVerifyAndDecodeAccessToken;
81
- const { isValid, errorCase, errorMessage, decodedAccessToken, decodedAccessToken_original } = await verifyAndDecodeAccessToken({ accessToken });
82
- if (!isValid) {
83
- return {
84
- isValid: false,
85
- errorMessage: `${errorCase}: ${errorMessage}`,
86
- wwwAuthenticateHeaderErrorDescription: (() => {
87
- switch (errorCase) {
88
- case "does not respect schema":
89
- return "The access token is malformed or missing required claims";
90
- case "expired":
91
- return "The access token expired";
92
- case "invalid signature":
93
- return "The access token signature is invalid";
94
- }
95
- })()
96
- };
97
- }
98
- if (expectedAudience !== undefined) {
99
- const aud_array = typeof decodedAccessToken_original.aud === "string"
100
- ? [decodedAccessToken_original.aud]
101
- : decodedAccessToken_original.aud;
102
- if (!aud_array.includes(expectedAudience)) {
103
- return {
104
- isValid: false,
105
- errorMessage: [
106
- "Access token is not for the expected audience.",
107
- `Got aud claim: ${JSON.stringify(decodedAccessToken_original.aud)}`,
108
- `Expected: ${expectedAudience}`
109
- ].join(" "),
110
- wwwAuthenticateHeaderErrorDescription: "The access token audience is invalid"
111
- };
112
- }
93
+ const validateAndGetAccessTokenClaims = async ({ request }) => {
94
+ const validateAndDecodeAccessToken = await prValidateAndDecodeAccessToken;
95
+ const { isSuccess, errorCause, debugErrorMessage, decodedAccessToken, accessToken } = await validateAndDecodeAccessToken({
96
+ request
97
+ });
98
+ if (!isSuccess) {
99
+ if (errorCause === "missing Authorization header") {
100
+ return id({
101
+ isSuccess: false,
102
+ isAnonymousRequest: true
103
+ });
113
104
  }
114
- return {
115
- isValid: true,
116
- accessTokenClaims: decodedAccessToken
117
- };
105
+ return id({
106
+ isSuccess: false,
107
+ isAnonymousRequest: false,
108
+ debugErrorMessage: `${errorCause}: ${debugErrorMessage}`,
109
+ wwwAuthenticateResponseHeaderValue: `Bearer error="invalid_token", error_description="${(() => {
110
+ switch (errorCause) {
111
+ case "validation error":
112
+ case "validation error - invalid signature":
113
+ case "validation error - access token expired":
114
+ return "Validation Failed";
115
+ default:
116
+ assert(false);
117
+ }
118
+ })()}"`
119
+ });
118
120
  }
121
+ return id({
122
+ isSuccess: true,
123
+ accessTokenClaims: decodedAccessToken,
124
+ accessToken
125
+ });
119
126
  };
127
+ return { validateAndGetAccessTokenClaims };
120
128
  };
121
129
  return { createValidateAndGetAccessTokenClaims };
122
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"accessTokenValidation_rfc9068.mjs","sourceRoot":"","sources":["../../../src/tanstack-start/react/accessTokenValidation_rfc9068.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"accessTokenValidation_rfc9068.mjs","sourceRoot":"","sources":["../../../src/tanstack-start/react/accessTokenValidation_rfc9068.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gCAAgC,EAAE,MAAM,8CAA8C,CAAC;AAChG,OAAO,EAAE,MAAM,EAAe,EAAE,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AAExE,MAAM,UAAU,mDAAmD,CAEjE,MAOD;IACG,MAAM,EACF,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAAE,sBAAsB,EAC3C,GAAG,MAAM,CAAC;IAEX,MAAM,qCAAqC,GAEvC,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE;QAC1B,MAAM,8BAA8B,GAAG,CAAC,KAAK,IAAI,EAAE;YAC/C,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAEjE,MAAM,EAAE,aAAa,EAAE,4BAA4B,EAAE,GACjD,uBAAuB,KAAK,SAAS;gBACjC,CAAC,CAAE,cAAc,CAAC,WAAW,EAAY;gBACzC,CAAC,CAAC,cAAc;qBACT,mCAAmC,CAAC;oBACjC,wBAAwB,EAAE,uBAAuB;iBACpD,CAAC;qBACD,WAAW,EAAE,CAAC;YAE7B,QAAQ,iBAAiB,CAAC,cAAc,EAAE,CAAC;gBACvC,KAAK,MAAM;oBACP,CAAC;wBACG,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE;4BAC3B,IAAI,sBAAsB,KAAK,SAAS,EAAE,CAAC;gCACvC,OAAO,SAAS,CAAC;4BACrB,CAAC;4BAED,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;4BAE1C,MAAM,SAAS,GAAG,IAAI,KAAK,CACvB,EAAE,EACF;gCACI,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE;oCACpB,MAAM,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC;oCAEpC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oCAEnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;wCACtB,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wCAC7B,OAAO,EAAE,CAAC;oCACd,CAAC;oCAED,OAAO,KAAK,CAAC;gCACjB,CAAC;gCACD,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE;oCACpB,MAAM,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC;oCACpC,OAAO,IAAI,CAAC;gCAChB,CAAC;6BACJ,CACJ,CAAC;4BAEF,MAAM,gBAAgB,GAAG,sBAAsB,EAAE,CAAC;gCAC9C,iBAAiB;gCACjB,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE;6BAC9B,CAAC,CAAC;4BAEH,IAAI,CAAC,gBAAgB,EAAE,CAAC;gCACpB,MAAM,IAAI,KAAK,CACX;oCACI,+DAA+D;oCAC/D,oEAAoE;oCACpE,yBAAyB;oCACzB,eAAe,CAAC,IAAI,KAAK,CAAC;wCACtB,sCAAsC,KAAK,CAAC,IAAI,CAC5C,eAAe,CAClB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;iCACvB;qCACI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC;qCACxC,IAAI,CAAC,GAAG,CAAC,CACjB,CAAC;4BACN,CAAC;4BAED,OAAO,gBAAgB,CAAC;wBAC5B,CAAC,CAAC,EAAE,CAAC;wBAEL,MAAM,aAAa,CAAC;4BAChB,cAAc,EAAE,MAAM;4BACtB,SAAS,EAAE,iBAAiB,CAAC,SAAS;4BACtC,gBAAgB;yBACnB,CAAC,CAAC;oBACP,CAAC;oBACD,MAAM;gBACV,KAAK,MAAM;oBACP,CAAC;wBACG,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE;4BAClC,IAAI,iBAAiB,CAAC,sBAAsB,KAAK,SAAS,EAAE,CAAC;gCACzD,MAAM,CAAC,EAAE,CAAoB,iBAAiB,CAAC,sBAAsB,CAAC,CAAC,CAAC;gCACxE,OAAO,iBAAiB,CAAC,sBAAsB,CAAC;4BACpD,CAAC;4BAED,IAAI,sBAAsB,KAAK,SAAS,EAAE,CAAC;gCACvC,OAAO,sBAAsB,CAAC;4BAClC,CAAC;4BAED,OAAO,gCAAgC,CAAoB;gCACvD,YAAY,EAAE;oCACV,iEAAiE;oCACjE,mEAAmE;oCACnE,iDAAiD;oCACjD,6DAA6D;iCAChE,CAAC,IAAI,CAAC,GAAG,CAAC;6BACd,CAAC,CAAC;wBACP,CAAC,CAAC,EAAE,CAAC;wBAEL,MAAM,aAAa,CAAC;4BAChB,cAAc,EAAE,MAAM;4BACtB,QAAQ,EAAE,qBAAqB;4BAC/B,uBAAuB;yBAC1B,CAAC,CAAC;oBACP,CAAC;oBACD,MAAM;gBACV;oBACI,MAAM,CAA0C,KAAK,CAAC,CAAC;YAC/D,CAAC;YAED,OAAO,4BAA4B,CAAC;QACxC,CAAC,CAAC,EAAE,CAAC;QAEL,MAAM,+BAA+B,GAEjC,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YACtB,MAAM,4BAA4B,GAAG,MAAM,8BAA8B,CAAC;YAE1E,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,EAAE,GAC/E,MAAM,4BAA4B,CAAC;gBAC/B,OAAO;aACV,CAAC,CAAC;YAEP,IAAI,CAAC,SAAS,EAAE,CAAC;gBACb,IAAI,UAAU,KAAK,8BAA8B,EAAE,CAAC;oBAChD,OAAO,EAAE,CAAsE;wBAC3E,SAAS,EAAE,KAAK;wBAChB,kBAAkB,EAAE,IAAI;qBAC3B,CAAC,CAAC;gBACP,CAAC;gBAED,OAAO,EAAE,CAAsE;oBAC3E,SAAS,EAAE,KAAK;oBAChB,kBAAkB,EAAE,KAAK;oBACzB,iBAAiB,EAAE,GAAG,UAAU,KAAK,iBAAiB,EAAE;oBACxD,kCAAkC,EAAE,oDAAoD,CAAC,GAAG,EAAE;wBAC1F,QAAQ,UAAU,EAAE,CAAC;4BACjB,KAAK,kBAAkB,CAAC;4BACxB,KAAK,sCAAsC,CAAC;4BAC5C,KAAK,yCAAyC;gCAC1C,OAAO,mBAAmB,CAAC;4BAC/B;gCACI,MAAM,CAAmC,KAAK,CAAC,CAAC;wBACxD,CAAC;oBACL,CAAC,CAAC,EAAE,GAAG;iBACV,CAAC,CAAC;YACP,CAAC;YAED,OAAO,EAAE,CAAwE;gBAC7E,SAAS,EAAE,IAAI;gBACf,iBAAiB,EAAE,kBAAkB;gBACrC,WAAW;aACd,CAAC,CAAC;QACP,CAAC,CAAC;QAEF,OAAO,EAAE,+BAA+B,EAAE,CAAC;IAC/C,CAAC,CAAC;IAEF,OAAO,EAAE,qCAAqC,EAAE,CAAC;AACrD,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { CreateValidateAndGetAccessTokenClaims, OidcSpaApi } from "./types";
1
+ import type { CreateValidateAndGetAccessTokenClaims, OidcSpaUtils } from "./types";
2
2
  import type { ZodSchemaLike } from "../../tools/ZodSchemaLike";
3
3
  import type { Oidc as Oidc_core } from "../../core";
4
4
  export declare function createOidcSpaApi<AutoLogin extends boolean, DecodedIdToken extends Record<string, unknown>, AccessTokenClaims extends Record<string, unknown> | undefined>(params: {
@@ -6,4 +6,4 @@ export declare function createOidcSpaApi<AutoLogin extends boolean, DecodedIdTok
6
6
  decodedIdTokenSchema: ZodSchemaLike<Oidc_core.Tokens.DecodedIdToken_OidcCoreSpec, DecodedIdToken> | undefined;
7
7
  decodedIdToken_mock: DecodedIdToken | undefined;
8
8
  createValidateAndGetAccessTokenClaims: CreateValidateAndGetAccessTokenClaims<AccessTokenClaims> | undefined;
9
- }): OidcSpaApi<AutoLogin, DecodedIdToken, AccessTokenClaims>;
9
+ }): OidcSpaUtils<AutoLogin, DecodedIdToken, AccessTokenClaims>;
@@ -10,6 +10,7 @@ import { typeGuard } from "../../tools/tsafe/typeGuard.mjs";
10
10
  import { createServerFn, createMiddleware } from "@tanstack/react-start";
11
11
  // @ts-expect-error: Since our module is not labeled as ESM we don't have the types here.
12
12
  import { getRequest, setResponseHeader, setResponseStatus } from "@tanstack/react-start/server";
13
+ //import { getRequest, setResponseHeader, setResponseStatus } from "@tanstack/react-start-server";
13
14
  import { toFullyQualifiedUrl } from "../../tools/toFullyQualifiedUrl.mjs";
14
15
  import { BEFORE_LOAD_FN_BRAND_PROPERTY_NAME } from "./disableSsrIfLoginEnforced.mjs";
15
16
  import { setDesiredPostLoginRedirectUrl } from "../../core/desiredPostLoginRedirectUrl.mjs";
@@ -469,7 +470,8 @@ export function createOidcSpaApi(params) {
469
470
  __unsafe_clientSecret: paramsOfBootstrap.__unsafe_clientSecret,
470
471
  __metadata: paramsOfBootstrap.__metadata,
471
472
  __unsafe_useIdTokenAsAccessToken: paramsOfBootstrap.__unsafe_useIdTokenAsAccessToken,
472
- autoLogoutParams: paramsOfBootstrap.autoLogoutParams
473
+ autoLogoutParams: paramsOfBootstrap.autoLogoutParams,
474
+ dpop: paramsOfBootstrap.dpop
473
475
  });
474
476
  }
475
477
  catch (error) {
@@ -550,57 +552,64 @@ export function createOidcSpaApi(params) {
550
552
  return async (options) => {
551
553
  const { next } = options;
552
554
  const unauthorized = (params) => {
553
- const { errorMessage, wwwAuthenticateHeaderErrorDescription } = params;
554
- setResponseHeader("WWW-Authenticate", `Bearer error="invalid_token", error_description="${wwwAuthenticateHeaderErrorDescription}"`);
555
- setResponseStatus(401, "Unauthorized");
556
- return new Error(`oidc-spa: ${errorMessage}`);
557
- };
558
- const { headers } = getRequest();
559
- const authorizationHeaderValue = headers.get("Authorization");
560
- if (authorizationHeaderValue === null) {
561
- if (params?.assert === "user logged in") {
562
- const errorMessage = [
563
- "Asserted user logged in for that serverFn request",
564
- "but no access token was attached to the request"
565
- ].join(" ");
566
- throw unauthorized({
567
- errorMessage,
568
- wwwAuthenticateHeaderErrorDescription: errorMessage
569
- });
570
- }
571
- return next({
572
- context: {
573
- oidc: id(id({
574
- isUserLoggedIn: false
575
- }))
555
+ const { code, wwwAuthenticateResponseHeaderValue, debugErrorMessage } = params;
556
+ setResponseHeader("WWW-Authenticate", wwwAuthenticateResponseHeaderValue);
557
+ setResponseStatus(code, (() => {
558
+ switch (code) {
559
+ case 401:
560
+ return "Unauthorized";
561
+ case 403:
562
+ return "Forbidden";
563
+ default:
564
+ assert(false);
576
565
  }
577
- });
578
- }
579
- const accessToken = (() => {
580
- const prefix = "Bearer ";
581
- if (!authorizationHeaderValue.startsWith(prefix)) {
582
- return undefined;
566
+ })());
567
+ if (process.env.NODE_ENV === "development") {
568
+ console.error(`oidc-spa: ${debugErrorMessage}`);
583
569
  }
584
- return authorizationHeaderValue.slice(prefix.length);
585
- })();
586
- if (accessToken === undefined) {
587
- const errorMessage = "Missing well formed Authorization header with Bearer <access_token>";
588
- throw unauthorized({
589
- errorMessage,
590
- wwwAuthenticateHeaderErrorDescription: errorMessage
591
- });
592
- }
570
+ return new Error(`oidc-spa: ${wwwAuthenticateResponseHeaderValue}`);
571
+ };
593
572
  assert(prValidateAndGetAccessTokenClaims !== undefined);
594
573
  const { validateAndGetAccessTokenClaims } = await prValidateAndGetAccessTokenClaims;
595
- const resultOfValidate = await validateAndGetAccessTokenClaims({ accessToken });
596
- if (!resultOfValidate.isValid) {
597
- const { errorMessage, wwwAuthenticateHeaderErrorDescription } = resultOfValidate;
574
+ const { headers, url, method } = getRequest();
575
+ const resultOfValidate = await validateAndGetAccessTokenClaims({
576
+ request: {
577
+ url,
578
+ method,
579
+ headers: {
580
+ Authorization: headers.get("Authorization"),
581
+ DPoP: headers.get("DPoP")
582
+ }
583
+ }
584
+ });
585
+ if (!resultOfValidate.isSuccess) {
586
+ if (resultOfValidate.isAnonymousRequest) {
587
+ if (params?.assert === "user logged in") {
588
+ throw unauthorized({
589
+ code: 401,
590
+ wwwAuthenticateResponseHeaderValue: "Bearer error=\"invalid_request\", error_description=\"Missing access token\"",
591
+ debugErrorMessage: [
592
+ "Asserted user logged in for that serverFn request",
593
+ "but no access token was attached to the request"
594
+ ].join(" ")
595
+ });
596
+ }
597
+ return next({
598
+ context: {
599
+ oidc: id(id({
600
+ isUserLoggedIn: false
601
+ }))
602
+ }
603
+ });
604
+ }
605
+ const { debugErrorMessage, wwwAuthenticateResponseHeaderValue } = resultOfValidate;
598
606
  throw unauthorized({
599
- errorMessage,
600
- wwwAuthenticateHeaderErrorDescription
607
+ code: 401,
608
+ wwwAuthenticateResponseHeaderValue,
609
+ debugErrorMessage
601
610
  });
602
611
  }
603
- const { accessTokenClaims } = resultOfValidate;
612
+ const { accessTokenClaims, accessToken } = resultOfValidate;
604
613
  assert(is(accessTokenClaims));
605
614
  check_required_claims: {
606
615
  const getHasRequiredClaims = params?.hasRequiredClaims;
@@ -626,13 +635,13 @@ export function createOidcSpaApi(params) {
626
635
  if (hasRequiredClaims) {
627
636
  break check_required_claims;
628
637
  }
629
- const errorMessage = [
630
- "Missing or invalid required access token claim.",
631
- `Related to claims: ${Array.from(accessedClaimNames).join(" and/or ")}`
632
- ].join(" ");
633
638
  throw unauthorized({
634
- errorMessage,
635
- wwwAuthenticateHeaderErrorDescription: errorMessage
639
+ code: 403,
640
+ wwwAuthenticateResponseHeaderValue: "Bearer error=\"insufficient_scope\", error_description=\"Insufficient privileges\"",
641
+ debugErrorMessage: [
642
+ "Missing or invalid required access token claim.",
643
+ `Related to claims: ${Array.from(accessedClaimNames).join(" and/or ")}`
644
+ ].join(" ")
636
645
  });
637
646
  }
638
647
  return next({