@hearth-auth/node 0.0.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 (85) hide show
  1. package/dist/admin.d.ts +83 -0
  2. package/dist/admin.d.ts.map +1 -0
  3. package/dist/admin.js +184 -0
  4. package/dist/admin.js.map +1 -0
  5. package/dist/admin.test.d.ts +2 -0
  6. package/dist/admin.test.d.ts.map +1 -0
  7. package/dist/admin.test.js +239 -0
  8. package/dist/admin.test.js.map +1 -0
  9. package/dist/authorize.d.ts +35 -0
  10. package/dist/authorize.d.ts.map +1 -0
  11. package/dist/authorize.js +68 -0
  12. package/dist/authorize.js.map +1 -0
  13. package/dist/authorize.test.d.ts +2 -0
  14. package/dist/authorize.test.d.ts.map +1 -0
  15. package/dist/authorize.test.js +93 -0
  16. package/dist/authorize.test.js.map +1 -0
  17. package/dist/client.d.ts +36 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +51 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/config.d.ts +47 -0
  22. package/dist/config.d.ts.map +1 -0
  23. package/dist/config.js +33 -0
  24. package/dist/config.js.map +1 -0
  25. package/dist/config.test.d.ts +2 -0
  26. package/dist/config.test.d.ts.map +1 -0
  27. package/dist/config.test.js +36 -0
  28. package/dist/config.test.js.map +1 -0
  29. package/dist/discovery.d.ts +22 -0
  30. package/dist/discovery.d.ts.map +1 -0
  31. package/dist/discovery.js +60 -0
  32. package/dist/discovery.js.map +1 -0
  33. package/dist/discovery.test.d.ts +2 -0
  34. package/dist/discovery.test.d.ts.map +1 -0
  35. package/dist/discovery.test.js +77 -0
  36. package/dist/discovery.test.js.map +1 -0
  37. package/dist/errors.d.ts +120 -0
  38. package/dist/errors.d.ts.map +1 -0
  39. package/dist/errors.js +172 -0
  40. package/dist/errors.js.map +1 -0
  41. package/dist/errors.test.d.ts +2 -0
  42. package/dist/errors.test.d.ts.map +1 -0
  43. package/dist/errors.test.js +89 -0
  44. package/dist/errors.test.js.map +1 -0
  45. package/dist/index.d.ts +16 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +18 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/introspect.d.ts +37 -0
  50. package/dist/introspect.d.ts.map +1 -0
  51. package/dist/introspect.js +72 -0
  52. package/dist/introspect.js.map +1 -0
  53. package/dist/introspect.test.d.ts +2 -0
  54. package/dist/introspect.test.d.ts.map +1 -0
  55. package/dist/introspect.test.js +109 -0
  56. package/dist/introspect.test.js.map +1 -0
  57. package/dist/jwks.d.ts +26 -0
  58. package/dist/jwks.d.ts.map +1 -0
  59. package/dist/jwks.js +106 -0
  60. package/dist/jwks.js.map +1 -0
  61. package/dist/jwks.test.d.ts +7 -0
  62. package/dist/jwks.test.d.ts.map +1 -0
  63. package/dist/jwks.test.js +154 -0
  64. package/dist/jwks.test.js.map +1 -0
  65. package/dist/middleware.d.ts +61 -0
  66. package/dist/middleware.d.ts.map +1 -0
  67. package/dist/middleware.js +228 -0
  68. package/dist/middleware.js.map +1 -0
  69. package/dist/middleware.mode.test.d.ts +2 -0
  70. package/dist/middleware.mode.test.d.ts.map +1 -0
  71. package/dist/middleware.mode.test.js +203 -0
  72. package/dist/middleware.mode.test.js.map +1 -0
  73. package/dist/middleware.test.d.ts +2 -0
  74. package/dist/middleware.test.d.ts.map +1 -0
  75. package/dist/middleware.test.js +144 -0
  76. package/dist/middleware.test.js.map +1 -0
  77. package/dist/token.d.ts +68 -0
  78. package/dist/token.d.ts.map +1 -0
  79. package/dist/token.js +111 -0
  80. package/dist/token.js.map +1 -0
  81. package/dist/token.test.d.ts +2 -0
  82. package/dist/token.test.d.ts.map +1 -0
  83. package/dist/token.test.js +135 -0
  84. package/dist/token.test.js.map +1 -0
  85. package/package.json +40 -0
@@ -0,0 +1,120 @@
1
+ /** §5 — Hearth Node SDK error taxonomy. */
2
+ /** Base class for all @hearth-auth/node errors. Messages are sanitized to remove tokens/secrets. */
3
+ export declare class HearthError extends Error {
4
+ constructor(message: string, options?: {
5
+ cause?: unknown;
6
+ });
7
+ }
8
+ /** Thrown when the HearthClient is misconfigured (missing required fields, invalid URLs). */
9
+ export declare class ConfigurationError extends HearthError {
10
+ constructor(message: string, options?: {
11
+ cause?: unknown;
12
+ });
13
+ }
14
+ /** Thrown when OIDC discovery (/.well-known/openid-configuration) fails. */
15
+ export declare class DiscoveryError extends HearthError {
16
+ constructor(message: string, options?: {
17
+ cause?: unknown;
18
+ });
19
+ }
20
+ /** Thrown when fetching or parsing the JWKS document fails. */
21
+ export declare class JWKSFetchError extends HearthError {
22
+ constructor(message: string, options?: {
23
+ cause?: unknown;
24
+ });
25
+ }
26
+ /** Thrown when token signature verification fails or the token is structurally invalid. */
27
+ export declare class TokenVerificationError extends HearthError {
28
+ constructor(message: string, options?: {
29
+ cause?: unknown;
30
+ });
31
+ }
32
+ /** Thrown when token `exp` claim is in the past (beyond clock skew tolerance). */
33
+ export declare class TokenExpiredError extends TokenVerificationError {
34
+ constructor(expiredAt: Date, options?: {
35
+ cause?: unknown;
36
+ });
37
+ }
38
+ /** Thrown when token `nbf` claim is in the future (beyond clock skew tolerance). */
39
+ export declare class TokenNotYetValidError extends TokenVerificationError {
40
+ constructor(notBefore: Date, options?: {
41
+ cause?: unknown;
42
+ });
43
+ }
44
+ /** Thrown when token signature is invalid, the JWT is malformed, or the algorithm does not match. */
45
+ export declare class TokenInvalidError extends TokenVerificationError {
46
+ constructor(message: string, options?: {
47
+ cause?: unknown;
48
+ });
49
+ }
50
+ /** Thrown when the `iss` claim does not match the configured issuer URL. */
51
+ export declare class TokenIssuerError extends TokenVerificationError {
52
+ constructor(actualIssuer: string, options?: {
53
+ cause?: unknown;
54
+ });
55
+ }
56
+ /** Thrown when the `aud` claim does not contain the expected audience. */
57
+ export declare class TokenAudienceError extends TokenVerificationError {
58
+ constructor(expectedAudience: string, options?: {
59
+ cause?: unknown;
60
+ });
61
+ }
62
+ /** Thrown when a required claim is missing, wrong type, or fails validation (iss, aud, iat). */
63
+ export declare class TokenClaimsError extends TokenVerificationError {
64
+ constructor(message: string, options?: {
65
+ cause?: unknown;
66
+ });
67
+ }
68
+ /** Thrown when the introspection request fails or returns an unexpected response. */
69
+ export declare class IntrospectionError extends HearthError {
70
+ constructor(message: string, options?: {
71
+ cause?: unknown;
72
+ });
73
+ }
74
+ /** Thrown by Express/Fastify middleware when configuration is invalid or setup fails. */
75
+ export declare class MiddlewareError extends HearthError {
76
+ constructor(message: string, options?: {
77
+ cause?: unknown;
78
+ });
79
+ }
80
+ /**
81
+ * Thrown when the introspection response echoes an `access_token_authorization` mode
82
+ * that does not match the SDK's configured `expectedMode`.
83
+ */
84
+ export declare class AuthorizationModeError extends HearthError {
85
+ readonly expected: string;
86
+ readonly actual: string;
87
+ constructor(expected: string, actual: string, options?: {
88
+ cause?: unknown;
89
+ });
90
+ }
91
+ /** Thrown when the `POST /oauth/authorize` request cannot be made (misconfiguration). */
92
+ export declare class AuthorizeError extends HearthError {
93
+ constructor(message: string, options?: {
94
+ cause?: unknown;
95
+ });
96
+ }
97
+ /**
98
+ * Thrown when a token with `token_type === "required_action"` is presented as a regular access
99
+ * token, or when the server returns `error_code: "HEARTH_REQUIRED_ACTIONS_PENDING"`.
100
+ */
101
+ export declare class RequiredActionError extends HearthError {
102
+ /** Pending action names from the token's `required_actions` claim. */
103
+ readonly requiredActions: string[];
104
+ /** Optional URL to the Hearth interstitial page for completing required actions. */
105
+ readonly redirectUri: string | undefined;
106
+ constructor(requiredActions: string[], redirectUri?: string, options?: {
107
+ cause?: unknown;
108
+ });
109
+ }
110
+ /**
111
+ * Typed HTTP error for AdminClient operations that return 4xx/5xx responses
112
+ * not covered by the standard error taxonomy.
113
+ */
114
+ export declare class AdminHttpError extends HearthError {
115
+ readonly status: number;
116
+ constructor(status: number, message: string, options?: {
117
+ cause?: unknown;
118
+ });
119
+ }
120
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/errors.js ADDED
@@ -0,0 +1,172 @@
1
+ /** §5 — Hearth Node SDK error taxonomy. */
2
+ const REDACTED = "[redacted]";
3
+ // Charcode ranges for base64url alphabet — used by sanitize() to avoid a backtracking regex.
4
+ function isB64UrlCode(code) {
5
+ return (code >= 65 && code <= 90) // A-Z
6
+ || (code >= 97 && code <= 122) // a-z
7
+ || (code >= 48 && code <= 57) // 0-9
8
+ || code === 95 // _
9
+ || code === 45; // -
10
+ }
11
+ function sanitize(value) {
12
+ // Linear O(n) scan — redacts JWT-shaped tokens (eyJ<seg>.<seg>.<seg>) without a
13
+ // backtracking regex (which is ReDoS-vulnerable on crafted inputs like "eyJeyJeyJ…").
14
+ let out = "";
15
+ let i = 0;
16
+ while (i < value.length) {
17
+ if (value[i] === "e" && value[i + 1] === "y" && value[i + 2] === "J") {
18
+ const start = i;
19
+ i += 3;
20
+ while (i < value.length && isB64UrlCode(value.charCodeAt(i)))
21
+ i++;
22
+ if (i < value.length && value[i] === ".") {
23
+ const dot1 = i++;
24
+ const seg2Start = i;
25
+ while (i < value.length && isB64UrlCode(value.charCodeAt(i)))
26
+ i++;
27
+ if (i > seg2Start && i < value.length && value[i] === ".") {
28
+ i++;
29
+ while (i < value.length && isB64UrlCode(value.charCodeAt(i)))
30
+ i++;
31
+ out += REDACTED;
32
+ continue;
33
+ }
34
+ // Two-segment prefix — not a JWT; emit up to and including the dot, re-scan remainder.
35
+ out += value.slice(start, dot1 + 1);
36
+ i = dot1 + 1;
37
+ continue;
38
+ }
39
+ out += value.slice(start, i);
40
+ continue;
41
+ }
42
+ out += value[i++];
43
+ }
44
+ return out;
45
+ }
46
+ /** Base class for all @hearth-auth/node errors. Messages are sanitized to remove tokens/secrets. */
47
+ export class HearthError extends Error {
48
+ constructor(message, options) {
49
+ super(sanitize(message), options);
50
+ this.name = this.constructor.name;
51
+ if (Error.captureStackTrace)
52
+ Error.captureStackTrace(this, this.constructor);
53
+ }
54
+ }
55
+ /** Thrown when the HearthClient is misconfigured (missing required fields, invalid URLs). */
56
+ export class ConfigurationError extends HearthError {
57
+ constructor(message, options) {
58
+ super(message, options);
59
+ }
60
+ }
61
+ /** Thrown when OIDC discovery (/.well-known/openid-configuration) fails. */
62
+ export class DiscoveryError extends HearthError {
63
+ constructor(message, options) {
64
+ super(message, options);
65
+ }
66
+ }
67
+ /** Thrown when fetching or parsing the JWKS document fails. */
68
+ export class JWKSFetchError extends HearthError {
69
+ constructor(message, options) {
70
+ super(message, options);
71
+ }
72
+ }
73
+ /** Thrown when token signature verification fails or the token is structurally invalid. */
74
+ export class TokenVerificationError extends HearthError {
75
+ constructor(message, options) {
76
+ super(message, options);
77
+ }
78
+ }
79
+ /** Thrown when token `exp` claim is in the past (beyond clock skew tolerance). */
80
+ export class TokenExpiredError extends TokenVerificationError {
81
+ constructor(expiredAt, options) {
82
+ super(`Token expired at ${expiredAt.toISOString()}`, options);
83
+ }
84
+ }
85
+ /** Thrown when token `nbf` claim is in the future (beyond clock skew tolerance). */
86
+ export class TokenNotYetValidError extends TokenVerificationError {
87
+ constructor(notBefore, options) {
88
+ super(`Token not valid until ${notBefore.toISOString()}`, options);
89
+ }
90
+ }
91
+ /** Thrown when token signature is invalid, the JWT is malformed, or the algorithm does not match. */
92
+ export class TokenInvalidError extends TokenVerificationError {
93
+ constructor(message, options) {
94
+ super(message, options);
95
+ }
96
+ }
97
+ /** Thrown when the `iss` claim does not match the configured issuer URL. */
98
+ export class TokenIssuerError extends TokenVerificationError {
99
+ constructor(actualIssuer, options) {
100
+ super(`Token issuer "${actualIssuer}" does not match configured issuer`, options);
101
+ }
102
+ }
103
+ /** Thrown when the `aud` claim does not contain the expected audience. */
104
+ export class TokenAudienceError extends TokenVerificationError {
105
+ constructor(expectedAudience, options) {
106
+ super(`Token audience does not contain expected value "${expectedAudience}"`, options);
107
+ }
108
+ }
109
+ /** Thrown when a required claim is missing, wrong type, or fails validation (iss, aud, iat). */
110
+ export class TokenClaimsError extends TokenVerificationError {
111
+ constructor(message, options) {
112
+ super(message, options);
113
+ }
114
+ }
115
+ /** Thrown when the introspection request fails or returns an unexpected response. */
116
+ export class IntrospectionError extends HearthError {
117
+ constructor(message, options) {
118
+ super(message, options);
119
+ }
120
+ }
121
+ /** Thrown by Express/Fastify middleware when configuration is invalid or setup fails. */
122
+ export class MiddlewareError extends HearthError {
123
+ constructor(message, options) {
124
+ super(message, options);
125
+ }
126
+ }
127
+ /**
128
+ * Thrown when the introspection response echoes an `access_token_authorization` mode
129
+ * that does not match the SDK's configured `expectedMode`.
130
+ */
131
+ export class AuthorizationModeError extends HearthError {
132
+ expected;
133
+ actual;
134
+ constructor(expected, actual, options) {
135
+ super(`Expected authorization mode "${expected}" but server echoed "${actual}"`, options);
136
+ this.expected = expected;
137
+ this.actual = actual;
138
+ }
139
+ }
140
+ /** Thrown when the `POST /oauth/authorize` request cannot be made (misconfiguration). */
141
+ export class AuthorizeError extends HearthError {
142
+ constructor(message, options) {
143
+ super(message, options);
144
+ }
145
+ }
146
+ /**
147
+ * Thrown when a token with `token_type === "required_action"` is presented as a regular access
148
+ * token, or when the server returns `error_code: "HEARTH_REQUIRED_ACTIONS_PENDING"`.
149
+ */
150
+ export class RequiredActionError extends HearthError {
151
+ /** Pending action names from the token's `required_actions` claim. */
152
+ requiredActions;
153
+ /** Optional URL to the Hearth interstitial page for completing required actions. */
154
+ redirectUri;
155
+ constructor(requiredActions, redirectUri, options) {
156
+ super(`Token requires completion of required actions: ${requiredActions.join(", ") || "(none)"}`, options);
157
+ this.requiredActions = requiredActions;
158
+ this.redirectUri = redirectUri;
159
+ }
160
+ }
161
+ /**
162
+ * Typed HTTP error for AdminClient operations that return 4xx/5xx responses
163
+ * not covered by the standard error taxonomy.
164
+ */
165
+ export class AdminHttpError extends HearthError {
166
+ status;
167
+ constructor(status, message, options) {
168
+ super(message, options);
169
+ this.status = status;
170
+ }
171
+ }
172
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../src/errors.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,89 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { HearthError, ConfigurationError, DiscoveryError, JWKSFetchError, TokenVerificationError, TokenExpiredError, TokenNotYetValidError, TokenInvalidError, TokenIssuerError, TokenAudienceError, TokenClaimsError, IntrospectionError, MiddlewareError, RequiredActionError, } from "./errors.js";
3
+ describe("HearthError taxonomy", () => {
4
+ it("all error classes extend HearthError", () => {
5
+ const classes = [
6
+ ConfigurationError,
7
+ DiscoveryError,
8
+ JWKSFetchError,
9
+ TokenVerificationError,
10
+ TokenClaimsError,
11
+ IntrospectionError,
12
+ MiddlewareError,
13
+ TokenInvalidError,
14
+ TokenIssuerError,
15
+ TokenAudienceError,
16
+ ];
17
+ for (const Cls of classes) {
18
+ const err = new Cls("test");
19
+ expect(err).toBeInstanceOf(HearthError);
20
+ expect(err).toBeInstanceOf(Cls);
21
+ expect(err.name).toBe(Cls.name);
22
+ }
23
+ });
24
+ it("TokenExpiredError extends TokenVerificationError", () => {
25
+ const err = new TokenExpiredError(new Date());
26
+ expect(err).toBeInstanceOf(HearthError);
27
+ expect(err).toBeInstanceOf(TokenVerificationError);
28
+ expect(err).toBeInstanceOf(TokenExpiredError);
29
+ });
30
+ it("TokenNotYetValidError extends TokenVerificationError", () => {
31
+ const d = new Date("2099-01-01T00:00:00Z");
32
+ const err = new TokenNotYetValidError(d);
33
+ expect(err).toBeInstanceOf(HearthError);
34
+ expect(err).toBeInstanceOf(TokenVerificationError);
35
+ expect(err).toBeInstanceOf(TokenNotYetValidError);
36
+ expect(err.message).toContain("2099-01-01T00:00:00.000Z");
37
+ expect(err.name).toBe("TokenNotYetValidError");
38
+ });
39
+ it("TokenInvalidError extends TokenVerificationError", () => {
40
+ const err = new TokenInvalidError("bad signature");
41
+ expect(err).toBeInstanceOf(TokenVerificationError);
42
+ expect(err.name).toBe("TokenInvalidError");
43
+ });
44
+ it("TokenIssuerError extends TokenVerificationError", () => {
45
+ const err = new TokenIssuerError("https://wrong.example.com");
46
+ expect(err).toBeInstanceOf(TokenVerificationError);
47
+ expect(err.name).toBe("TokenIssuerError");
48
+ expect(err.message).toContain("https://wrong.example.com");
49
+ });
50
+ it("TokenAudienceError extends TokenVerificationError", () => {
51
+ const err = new TokenAudienceError("my-client");
52
+ expect(err).toBeInstanceOf(TokenVerificationError);
53
+ expect(err.name).toBe("TokenAudienceError");
54
+ expect(err.message).toContain("my-client");
55
+ });
56
+ it("RequiredActionError exposes requiredActions and optional redirectUri", () => {
57
+ const err = new RequiredActionError(["VERIFY_EMAIL", "UPDATE_PASSWORD"]);
58
+ expect(err).toBeInstanceOf(HearthError);
59
+ expect(err.name).toBe("RequiredActionError");
60
+ expect(err.requiredActions).toEqual(["VERIFY_EMAIL", "UPDATE_PASSWORD"]);
61
+ expect(err.redirectUri).toBeUndefined();
62
+ });
63
+ it("RequiredActionError accepts optional redirectUri", () => {
64
+ const err = new RequiredActionError(["VERIFY_EMAIL"], "https://auth.example.com/ui/required-actions");
65
+ expect(err.requiredActions).toEqual(["VERIFY_EMAIL"]);
66
+ expect(err.redirectUri).toBe("https://auth.example.com/ui/required-actions");
67
+ });
68
+ it("supports cause chaining", () => {
69
+ const cause = new Error("original");
70
+ const err = new DiscoveryError("wrapped", { cause });
71
+ expect(err.cause).toBe(cause);
72
+ });
73
+ it("sanitizes JWT-like strings from messages", () => {
74
+ const fakeJwt = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyMSJ9.abc123";
75
+ const err = new HearthError(`Token was: ${fakeJwt}`);
76
+ expect(err.message).not.toContain(fakeJwt);
77
+ expect(err.message).toContain("[redacted]");
78
+ });
79
+ it("TokenExpiredError formats expiry date in message", () => {
80
+ const date = new Date("2024-01-01T00:00:00Z");
81
+ const err = new TokenExpiredError(date);
82
+ expect(err.message).toContain("2024-01-01T00:00:00.000Z");
83
+ });
84
+ it("TokenVerificationError is instance of TokenVerificationError via TokenExpiredError", () => {
85
+ const err = new TokenExpiredError(new Date());
86
+ expect(err).toBeInstanceOf(TokenVerificationError);
87
+ });
88
+ });
89
+ //# sourceMappingURL=errors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../src/errors.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** @hearth-auth/node — server-side Hearth SDK for Node.js. Public API surface. */
2
+ export { HearthClient } from "./client.js";
3
+ export type { HearthConfig } from "./config.js";
4
+ export { JwksVerifier } from "./jwks.js";
5
+ export { IntrospectionClient } from "./introspect.js";
6
+ export type { IntrospectionResult } from "./introspect.js";
7
+ export { VerifiedToken } from "./token.js";
8
+ export type { AccessTokenAuthorizationMode } from "./token.js";
9
+ export { HearthError, ConfigurationError, DiscoveryError, JWKSFetchError, TokenVerificationError, TokenExpiredError, TokenNotYetValidError, TokenInvalidError, TokenIssuerError, TokenAudienceError, TokenClaimsError, IntrospectionError, MiddlewareError, AuthorizationModeError, AuthorizeError, RequiredActionError, AdminHttpError, } from "./errors.js";
10
+ export { hearthMiddleware, hearthFastifyHook } from "./middleware.js";
11
+ export type { MiddlewareOptions } from "./middleware.js";
12
+ export { AuthorizeClient } from "./authorize.js";
13
+ export type { AuthorizeOptions, AuthorizeResult } from "./authorize.js";
14
+ export { AdminClient } from "./admin.js";
15
+ export type { AdminClientConfig, PageOptions, PageResponse } from "./admin.js";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAGlF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAG/D,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGzD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGxE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /** @hearth-auth/node — server-side Hearth SDK for Node.js. Public API surface. */
2
+ // §1 — Configuration & unified client
3
+ export { HearthClient } from "./client.js";
4
+ // §2 — Token verification
5
+ export { JwksVerifier } from "./jwks.js";
6
+ // §3 — Token introspection
7
+ export { IntrospectionClient } from "./introspect.js";
8
+ // §4 — Claims API
9
+ export { VerifiedToken } from "./token.js";
10
+ // §5 — Error taxonomy
11
+ export { HearthError, ConfigurationError, DiscoveryError, JWKSFetchError, TokenVerificationError, TokenExpiredError, TokenNotYetValidError, TokenInvalidError, TokenIssuerError, TokenAudienceError, TokenClaimsError, IntrospectionError, MiddlewareError, AuthorizationModeError, AuthorizeError, RequiredActionError, AdminHttpError, } from "./errors.js";
12
+ // §6 — Middleware
13
+ export { hearthMiddleware, hearthFastifyHook } from "./middleware.js";
14
+ // §7 — Decision client (POST /oauth/authorize)
15
+ export { AuthorizeClient } from "./authorize.js";
16
+ // §12 — Admin SDK
17
+ export { AdminClient } from "./admin.js";
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,sCAAsC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,0BAA0B;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,2BAA2B;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtD,kBAAkB;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,sBAAsB;AACtB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,kBAAkB;AAClB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGtE,+CAA+C;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,kBAAkB;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,37 @@
1
+ /** §3 — Token introspection per RFC 7662. */
2
+ import type { ResolvedConfig } from "./config.js";
3
+ import type { OidcDiscovery } from "./discovery.js";
4
+ import type { AccessTokenAuthorizationMode } from "./token.js";
5
+ /** RFC 7662 introspection response — required fields per spec §3. */
6
+ export interface IntrospectionResult {
7
+ active: boolean;
8
+ sub?: string;
9
+ iss?: string;
10
+ aud?: string | string[];
11
+ exp?: number;
12
+ iat?: number;
13
+ scope?: string;
14
+ /**
15
+ * Access-token authorization mode echoed from the server (HEA-922).
16
+ * Present when the introspecting client has a non-Embedded mode configured.
17
+ */
18
+ mode?: AccessTokenAuthorizationMode;
19
+ /** Live permissions — populated for Introspection/Decision mode clients. */
20
+ permissions?: string[];
21
+ /** Live roles — populated for Introspection/Decision mode clients. */
22
+ roles?: string[];
23
+ /** Live group slugs — populated for Introspection/Decision mode clients. */
24
+ groups?: string[];
25
+ /** Catch-all for non-standard claims returned by the server. */
26
+ extra: Record<string, unknown>;
27
+ }
28
+ export declare class IntrospectionClient {
29
+ private readonly config;
30
+ private readonly getDiscovery;
31
+ private readonly credentials;
32
+ constructor(config: ResolvedConfig, getDiscovery: () => Promise<OidcDiscovery>);
33
+ private getIntrospectionEndpoint;
34
+ /** Introspect a token per RFC 7662. */
35
+ introspect(token: string, tokenTypeHint?: "access_token" | "refresh_token"): Promise<IntrospectionResult>;
36
+ }
37
+ //# sourceMappingURL=introspect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.d.ts","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAG7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE/D,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,4BAA4B,CAAC;IACpC,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAJ/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGlB,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC;YAO/C,wBAAwB;IAWtC,uCAAuC;IACjC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,cAAc,GAAG,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAmDhH"}
@@ -0,0 +1,72 @@
1
+ /** §3 — Token introspection per RFC 7662. */
2
+ import { IntrospectionError } from "./errors.js";
3
+ export class IntrospectionClient {
4
+ config;
5
+ getDiscovery;
6
+ credentials;
7
+ constructor(config, getDiscovery) {
8
+ this.config = config;
9
+ this.getDiscovery = getDiscovery;
10
+ this.credentials = Buffer.from(`${config.client_id}:${config.client_secret}`).toString("base64");
11
+ }
12
+ async getIntrospectionEndpoint() {
13
+ if (this.config.introspection_endpoint)
14
+ return this.config.introspection_endpoint;
15
+ const doc = await this.getDiscovery();
16
+ if (!doc.introspection_endpoint) {
17
+ throw new IntrospectionError("Introspection endpoint not found in OIDC discovery document and no override configured");
18
+ }
19
+ return doc.introspection_endpoint;
20
+ }
21
+ /** Introspect a token per RFC 7662. */
22
+ async introspect(token, tokenTypeHint) {
23
+ const endpoint = await this.getIntrospectionEndpoint();
24
+ const body = new URLSearchParams({ token });
25
+ if (tokenTypeHint)
26
+ body.set("token_type_hint", tokenTypeHint);
27
+ let res;
28
+ try {
29
+ const controller = new AbortController();
30
+ const timer = setTimeout(() => controller.abort(), this.config.http_timeout);
31
+ res = await fetch(endpoint, {
32
+ method: "POST",
33
+ headers: {
34
+ "Content-Type": "application/x-www-form-urlencoded",
35
+ Authorization: `Basic ${this.credentials}`,
36
+ },
37
+ body,
38
+ signal: controller.signal,
39
+ });
40
+ clearTimeout(timer);
41
+ }
42
+ catch (err) {
43
+ throw new IntrospectionError("Introspection request failed", { cause: err });
44
+ }
45
+ if (!res.ok) {
46
+ throw new IntrospectionError(`Introspection endpoint returned HTTP ${res.status}`);
47
+ }
48
+ let raw;
49
+ try {
50
+ raw = await res.json();
51
+ }
52
+ catch (err) {
53
+ throw new IntrospectionError("Introspection response is not valid JSON", { cause: err });
54
+ }
55
+ const { active, sub, iss, aud, exp, iat, scope, mode, permissions, roles, groups, ...rest } = raw;
56
+ return {
57
+ active: Boolean(active),
58
+ sub: typeof sub === "string" ? sub : undefined,
59
+ iss: typeof iss === "string" ? iss : undefined,
60
+ aud: typeof aud === "string" || Array.isArray(aud) ? aud : undefined,
61
+ exp: typeof exp === "number" ? exp : undefined,
62
+ iat: typeof iat === "number" ? iat : undefined,
63
+ scope: typeof scope === "string" ? scope : undefined,
64
+ mode: typeof mode === "string" ? mode : undefined,
65
+ permissions: Array.isArray(permissions) ? permissions.filter((p) => typeof p === "string") : undefined,
66
+ roles: Array.isArray(roles) ? roles.filter((r) => typeof r === "string") : undefined,
67
+ groups: Array.isArray(groups) ? groups.filter((g) => typeof g === "string") : undefined,
68
+ extra: rest,
69
+ };
70
+ }
71
+ }
72
+ //# sourceMappingURL=introspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.js","sourceRoot":"","sources":["../src/introspect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=introspect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introspect.test.d.ts","sourceRoot":"","sources":["../src/introspect.test.ts"],"names":[],"mappings":""}