@hearth-auth/sdk 0.0.1 → 1.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 (83) hide show
  1. package/dist/admin.d.ts +43 -0
  2. package/dist/admin.js +126 -0
  3. package/dist/admin.js.map +1 -0
  4. package/dist/browser-auth.d.ts +32 -0
  5. package/dist/browser-auth.js +99 -0
  6. package/dist/browser-auth.js.map +1 -0
  7. package/dist/claims.d.ts +86 -0
  8. package/dist/claims.js +137 -0
  9. package/dist/claims.js.map +1 -0
  10. package/dist/client.d.ts +77 -0
  11. package/dist/client.js +190 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/errors.d.ts +114 -0
  14. package/{src/errors.ts → dist/errors.js} +83 -97
  15. package/dist/errors.js.map +1 -0
  16. package/dist/hearth-client.d.ts +133 -0
  17. package/dist/hearth-client.js +192 -0
  18. package/dist/hearth-client.js.map +1 -0
  19. package/dist/hearth.d.ts +105 -0
  20. package/dist/hearth.js +109 -0
  21. package/dist/hearth.js.map +1 -0
  22. package/dist/index.d.ts +23 -0
  23. package/dist/index.js +22 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/introspection-client.d.ts +59 -0
  26. package/dist/introspection-client.js +36 -0
  27. package/dist/introspection-client.js.map +1 -0
  28. package/dist/jwks-client.d.ts +28 -0
  29. package/dist/jwks-client.js +28 -0
  30. package/dist/jwks-client.js.map +1 -0
  31. package/dist/middleware.d.ts +38 -0
  32. package/dist/middleware.js +51 -0
  33. package/dist/middleware.js.map +1 -0
  34. package/dist/pkce.d.ts +64 -0
  35. package/dist/pkce.js +64 -0
  36. package/dist/pkce.js.map +1 -0
  37. package/dist/react.d.ts +32 -0
  38. package/dist/react.js +41 -0
  39. package/dist/react.js.map +1 -0
  40. package/dist/session-version-cache.d.ts +50 -0
  41. package/dist/session-version-cache.js +129 -0
  42. package/dist/session-version-cache.js.map +1 -0
  43. package/dist/types.d.ts +168 -0
  44. package/dist/types.js +2 -0
  45. package/dist/types.js.map +1 -0
  46. package/package.json +13 -4
  47. package/CHANGELOG.md +0 -12
  48. package/src/admin.ts +0 -157
  49. package/src/browser-auth.ts +0 -130
  50. package/src/claims.ts +0 -180
  51. package/src/client.ts +0 -251
  52. package/src/generated/google/api/annotations_pb.ts +0 -44
  53. package/src/generated/google/api/http_pb.ts +0 -467
  54. package/src/generated/hearth/authz/v1/authz_pb.ts +0 -593
  55. package/src/generated/hearth/cluster/v1/raft_pb.ts +0 -183
  56. package/src/generated/hearth/events/v1/audit_pb.ts +0 -886
  57. package/src/generated/hearth/identity/v1/identity_pb.ts +0 -1673
  58. package/src/generated/hearth/identity/v1/oauth_pb.ts +0 -1138
  59. package/src/generated/hearth/rbac/v1/rbac_pb.ts +0 -2000
  60. package/src/hearth-client.ts +0 -288
  61. package/src/hearth.ts +0 -224
  62. package/src/index.ts +0 -106
  63. package/src/introspection-client.ts +0 -83
  64. package/src/jwks-client.ts +0 -45
  65. package/src/middleware.ts +0 -82
  66. package/src/pkce.ts +0 -129
  67. package/src/react.tsx +0 -57
  68. package/src/session-version-cache.ts +0 -167
  69. package/src/types.ts +0 -188
  70. package/tests/admin-crud.test.ts +0 -97
  71. package/tests/auth-flow.test.ts +0 -75
  72. package/tests/authorize.test.ts +0 -386
  73. package/tests/claims.test.ts +0 -159
  74. package/tests/hasPermission.test.ts +0 -152
  75. package/tests/hearth-client.test.ts +0 -243
  76. package/tests/helpers.ts +0 -90
  77. package/tests/jwks.test.ts +0 -62
  78. package/tests/pkce.test.ts +0 -210
  79. package/tests/react-useHasPermission.test.tsx +0 -92
  80. package/tests/required-action.test.ts +0 -276
  81. package/tests/session-version.test.ts +0 -391
  82. package/tsconfig.json +0 -16
  83. package/vitest.config.ts +0 -8
package/src/client.ts DELETED
@@ -1,251 +0,0 @@
1
- import { decodeJwt } from "jose";
2
- import { RequiredActionError } from "./errors.js";
3
- import type {
4
- AuthorizeParams,
5
- AuthorizeResponse,
6
- BootstrapResponse,
7
- JwksDocument,
8
- MePermissionsResponse,
9
- RegisterClientParams,
10
- OAuthClient,
11
- TokenExchangeParams,
12
- TokenResponse,
13
- UserInfoResponse,
14
- } from "./types.js";
15
-
16
- /** Parameters for the PKCE authorization-code callback handler (spec §7). */
17
- export interface HandleCallbackParams {
18
- /** Full callback URL including query parameters (`code`, `state`, etc.). */
19
- callbackUrl: string;
20
- /** OAuth 2.0 client ID. */
21
- clientId: string;
22
- /** Redirect URI registered for this client. */
23
- redirectUri: string;
24
- /** PKCE code verifier generated during `login()` (RFC 7636). */
25
- codeVerifier?: string;
26
- }
27
-
28
- /** Error thrown when the Hearth API returns an error. */
29
- export class HearthError extends Error {
30
- constructor(
31
- public readonly status: number,
32
- public readonly body: unknown,
33
- ) {
34
- super(`Hearth API error ${status}: ${JSON.stringify(body)}`);
35
- this.name = "HearthError";
36
- }
37
- }
38
-
39
- /** Configuration for HearthApiClient. */
40
- export interface HearthApiClientConfig {
41
- baseUrl: string;
42
- realmId: string;
43
- }
44
-
45
- /**
46
- * Low-level Hearth HTTP API client for auth code flows, token management,
47
- * JWKS retrieval, and live RBAC claim resolution.
48
- *
49
- * @deprecated Use {@link HearthClient} from `hearth-client.js` as the
50
- * recommended entry point. This class is kept as a lower-level primitive.
51
- */
52
- export class HearthApiClient {
53
- private readonly baseUrl: string;
54
- private readonly realmId: string;
55
-
56
- constructor(config: HearthApiClientConfig) {
57
- this.baseUrl = config.baseUrl.replace(/\/$/, "");
58
- this.realmId = config.realmId;
59
- }
60
-
61
- /** POST /admin/bootstrap — create realm, admin user, tokens (dev mode only). */
62
- static async bootstrap(baseUrl: string): Promise<BootstrapResponse> {
63
- const url = `${baseUrl.replace(/\/$/, "")}/admin/bootstrap`;
64
- const resp = await fetch(url, { method: "POST" });
65
- if (!resp.ok) {
66
- throw new HearthError(resp.status, await resp.json());
67
- }
68
- return resp.json() as Promise<BootstrapResponse>;
69
- }
70
-
71
- /** POST /clients — register an OAuth 2.0 client. */
72
- async registerClient(params: RegisterClientParams): Promise<OAuthClient> {
73
- return this.post("/clients", {
74
- client_name: params.clientName,
75
- redirect_uris: params.redirectUris,
76
- });
77
- }
78
-
79
- /** POST /authorize — initiate an authorization code flow. */
80
- async authorize(params: AuthorizeParams): Promise<AuthorizeResponse> {
81
- return this.post("/authorize", {
82
- client_id: params.clientId,
83
- redirect_uri: params.redirectUri,
84
- scope: params.scope,
85
- state: params.state,
86
- response_type: params.responseType ?? "code",
87
- user_id: params.userId,
88
- code_challenge: params.codeChallenge,
89
- code_challenge_method: params.codeChallengeMethod,
90
- nonce: params.nonce,
91
- });
92
- }
93
-
94
- /** POST /token — exchange an authorization code for tokens. */
95
- async exchangeCode(params: TokenExchangeParams): Promise<TokenResponse> {
96
- return this.post("/token", {
97
- client_id: params.clientId,
98
- code: params.code,
99
- redirect_uri: params.redirectUri,
100
- code_verifier: params.codeVerifier,
101
- });
102
- }
103
-
104
- /**
105
- * Handle a PKCE authorization-code callback (spec §7).
106
- *
107
- * Extracts the `code` from `callbackUrl`, exchanges it for tokens, then
108
- * inspects the JWT's `token_type` claim before returning:
109
- *
110
- * - If `token_type === "required_action"`: throws {@link RequiredActionError}
111
- * with `requiredActions` populated from the JWT's `required_actions` claim.
112
- * - If the callback URL contains `required_action_redirect_uri`: throws
113
- * {@link RequiredActionError} with `redirectUri` set to that value.
114
- * - Otherwise: returns the token response normally.
115
- */
116
- async handleCallback(params: HandleCallbackParams): Promise<TokenResponse> {
117
- const url = new URL(params.callbackUrl);
118
- const code = url.searchParams.get("code");
119
- const requiredActionRedirectUri = url.searchParams.get(
120
- "required_action_redirect_uri",
121
- );
122
-
123
- if (!code) {
124
- throw new Error("handleCallback: no authorization code found in callback URL");
125
- }
126
-
127
- const tokens = await this.exchangeCode({
128
- clientId: params.clientId,
129
- code,
130
- redirectUri: params.redirectUri,
131
- codeVerifier: params.codeVerifier,
132
- });
133
-
134
- // Decode the access token to read Hearth-specific claims.
135
- let jwtPayload: Record<string, unknown> = {};
136
- try {
137
- jwtPayload = decodeJwt(tokens.access_token) as Record<string, unknown>;
138
- } catch {
139
- // Non-JWT access tokens (opaque) skip required-action detection.
140
- }
141
-
142
- const tokenType = jwtPayload["token_type"];
143
- const requiredActions = Array.isArray(jwtPayload["required_actions"])
144
- ? (jwtPayload["required_actions"] as string[])
145
- : [];
146
-
147
- if (tokenType === "required_action") {
148
- throw new RequiredActionError(
149
- requiredActions,
150
- requiredActionRedirectUri ?? undefined,
151
- );
152
- }
153
-
154
- if (requiredActionRedirectUri !== null) {
155
- throw new RequiredActionError([], requiredActionRedirectUri);
156
- }
157
-
158
- return tokens;
159
- }
160
-
161
- /** POST /token — refresh tokens using a refresh token. */
162
- async refreshTokens(
163
- clientId: string,
164
- refreshToken: string,
165
- ): Promise<TokenResponse> {
166
- return this.post("/token", {
167
- client_id: clientId,
168
- grant_type: "refresh_token",
169
- refresh_token: refreshToken,
170
- });
171
- }
172
-
173
- /**
174
- * GET /v1/me/permissions — fetch the freshly-resolved RBAC claim set
175
- * for the bearer-token user.
176
- *
177
- * Unlike `hasPermission()` on a `createHearth()` client (which reads
178
- * the cached set from the JWT), this call queries the server and
179
- * reflects any role/group assignments made since the token was issued.
180
- */
181
- async permissions(accessToken: string): Promise<MePermissionsResponse> {
182
- const resp = await fetch(`${this.baseUrl}/v1/me/permissions`, {
183
- headers: {
184
- "X-Realm-ID": this.realmId,
185
- Authorization: `Bearer ${accessToken}`,
186
- },
187
- });
188
- if (!resp.ok) {
189
- throw new HearthError(resp.status, await resp.json());
190
- }
191
- return resp.json() as Promise<MePermissionsResponse>;
192
- }
193
-
194
- /** GET /userinfo — retrieve user claims using an access token. */
195
- async userinfo(accessToken: string): Promise<UserInfoResponse> {
196
- const resp = await fetch(`${this.baseUrl}/userinfo`, {
197
- headers: {
198
- "X-Realm-ID": this.realmId,
199
- Authorization: `Bearer ${accessToken}`,
200
- },
201
- });
202
- if (!resp.ok) {
203
- throw new HearthError(resp.status, await resp.json());
204
- }
205
- return resp.json() as Promise<UserInfoResponse>;
206
- }
207
-
208
- /** GET /jwks — retrieve the JWKS document. */
209
- async jwks(): Promise<JwksDocument> {
210
- const resp = await fetch(`${this.baseUrl}/jwks`);
211
- if (!resp.ok) {
212
- throw new HearthError(resp.status, await resp.json());
213
- }
214
- return resp.json() as Promise<JwksDocument>;
215
- }
216
-
217
- /** GET /.well-known/openid-configuration — OIDC discovery document. */
218
- async discovery(): Promise<Record<string, unknown>> {
219
- const resp = await fetch(
220
- `${this.baseUrl}/.well-known/openid-configuration`,
221
- );
222
- if (!resp.ok) {
223
- throw new HearthError(resp.status, await resp.json());
224
- }
225
- return resp.json() as Promise<Record<string, unknown>>;
226
- }
227
-
228
- /** Creates an AdminClient using the given access token. */
229
- admin(accessToken: string): AdminClient {
230
- return new AdminClient(this.baseUrl, this.realmId, accessToken);
231
- }
232
-
233
-
234
- private async post<T>(path: string, body: unknown): Promise<T> {
235
- const resp = await fetch(`${this.baseUrl}${path}`, {
236
- method: "POST",
237
- headers: {
238
- "Content-Type": "application/json",
239
- "X-Realm-ID": this.realmId,
240
- },
241
- body: JSON.stringify(body),
242
- });
243
- if (!resp.ok) {
244
- throw new HearthError(resp.status, await resp.json());
245
- }
246
- return resp.json() as Promise<T>;
247
- }
248
- }
249
-
250
- // AdminClient is imported here to avoid circular deps — it's re-exported from index.
251
- import { AdminClient } from "./admin.js";
@@ -1,44 +0,0 @@
1
- // Copyright 2015 Google LLC
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- // Vendored from github.com/googleapis/googleapis (Apache-2.0).
16
- // Kept minimal: only annotations.proto + http.proto are needed for
17
- // google.api.http method annotations. Replaces the buf.build remote
18
- // dependency so CI never needs the buf module cache hydrated.
19
-
20
- // @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
21
- // @generated from file google/api/annotations.proto (package google.api, syntax proto3)
22
- /* eslint-disable */
23
-
24
- import type { GenExtension, GenFile } from "@bufbuild/protobuf/codegenv2";
25
- import { extDesc, fileDesc } from "@bufbuild/protobuf/codegenv2";
26
- import type { HttpRule } from "./http_pb";
27
- import { file_google_api_http } from "./http_pb";
28
- import type { MethodOptions } from "@bufbuild/protobuf/wkt";
29
- import { file_google_protobuf_descriptor } from "@bufbuild/protobuf/wkt";
30
-
31
- /**
32
- * Describes the file google/api/annotations.proto.
33
- */
34
- export const file_google_api_annotations: GenFile = /*@__PURE__*/
35
- fileDesc("Chxnb29nbGUvYXBpL2Fubm90YXRpb25zLnByb3RvEgpnb29nbGUuYXBpOksKBGh0dHASHi5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxiwyrwiIAEoCzIULmdvb2dsZS5hcGkuSHR0cFJ1bGVSBGh0dHBCbgoOY29tLmdvb2dsZS5hcGlCEEFubm90YXRpb25zUHJvdG9QAVpBZ29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy9hcGkvYW5ub3RhdGlvbnM7YW5ub3RhdGlvbnOiAgRHQVBJYgZwcm90bzM", [file_google_api_http, file_google_protobuf_descriptor]);
36
-
37
- /**
38
- * See `HttpRule`.
39
- *
40
- * @generated from extension: google.api.HttpRule http = 72295728;
41
- */
42
- export const http: GenExtension<MethodOptions, HttpRule> = /*@__PURE__*/
43
- extDesc(file_google_api_annotations, 0);
44
-