@krutai/auth 0.2.3 → 0.4.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.
package/dist/index.d.ts CHANGED
@@ -1,150 +1,280 @@
1
- import * as better_auth from 'better-auth';
2
- import { BetterAuthOptions, Auth } from 'better-auth';
3
- export { BetterAuthOptions } from 'better-auth';
4
- export { ApiKeyValidationError, validateApiKeyFormat, validateApiKeyWithService } from 'krutai';
1
+ export { ApiKeyValidationError as KrutAuthKeyValidationError, validateApiKeyWithService as validateApiKey, validateApiKeyFormat } from 'krutai';
5
2
 
3
+ /**
4
+ * Types for @krutai/auth
5
+ *
6
+ * Pure fetch-based auth client — no local better-auth dependency.
7
+ */
8
+ /**
9
+ * Default base URL for the KrutAI server.
10
+ * Used when no serverUrl is provided in the config.
11
+ */
12
+ declare const DEFAULT_SERVER_URL: "http://localhost:8000";
13
+ /**
14
+ * Default path prefix for the auth routes on the server.
15
+ * The server mounts better-auth under this prefix.
16
+ */
17
+ declare const DEFAULT_AUTH_PREFIX: "/lib-auth";
6
18
  /**
7
19
  * Configuration options for KrutAuth
8
20
  */
9
21
  interface KrutAuthConfig {
10
22
  /**
11
- * API key for authentication with KrutAI services
23
+ * KrutAI API key.
24
+ * Validated against the server before use.
12
25
  * Optional: defaults to process.env.KRUTAI_API_KEY
13
26
  */
14
27
  apiKey?: string;
15
28
  /**
16
- * Better Auth configuration options
17
- * @see https://www.better-auth.com/docs
18
- */
19
- betterAuthOptions?: Partial<BetterAuthOptions>;
20
- /**
21
- * Whether to validate the API key on initialization
22
- * @default true
23
- */
24
- validateOnInit?: boolean;
25
- /**
26
- * Base URL of your deployed LangChain backend/validation server
29
+ * Base URL of your deployed KrutAI server.
27
30
  * @default "http://localhost:8000"
31
+ * @example "https://krut.ai"
28
32
  */
29
33
  serverUrl?: string;
30
34
  /**
31
- * Custom API validation endpoint
35
+ * Path prefix for the auth routes on the server.
36
+ * @default "/lib-auth"
32
37
  */
33
- validationEndpoint?: string;
38
+ authPrefix?: string;
39
+ /**
40
+ * Whether to validate the API key against the server on initialization.
41
+ * Set to false to skip the validation round-trip (e.g. in tests).
42
+ * @default true
43
+ */
44
+ validateOnInit?: boolean;
34
45
  }
35
46
  /**
36
- * Authentication session interface
47
+ * Parameters for email/password sign-up
48
+ */
49
+ interface SignUpEmailParams {
50
+ /** User email */
51
+ email: string;
52
+ /** User password */
53
+ password: string;
54
+ /** Display name */
55
+ name: string;
56
+ }
57
+ /**
58
+ * Parameters for email/password sign-in
59
+ */
60
+ interface SignInEmailParams {
61
+ /** User email */
62
+ email: string;
63
+ /** User password */
64
+ password: string;
65
+ }
66
+ /**
67
+ * A user record returned by the auth server
68
+ */
69
+ interface AuthUser {
70
+ id: string;
71
+ email: string;
72
+ name?: string;
73
+ emailVerified: boolean;
74
+ createdAt: string;
75
+ updatedAt: string;
76
+ [key: string]: unknown;
77
+ }
78
+ /**
79
+ * A session record returned by the auth server
80
+ */
81
+ interface AuthSessionRecord {
82
+ id: string;
83
+ userId: string;
84
+ token: string;
85
+ expiresAt: string;
86
+ [key: string]: unknown;
87
+ }
88
+ /**
89
+ * Combined session + user response
37
90
  */
38
91
  interface AuthSession {
39
- user: {
40
- id: string;
41
- email: string;
42
- name?: string;
43
- [key: string]: unknown;
44
- };
45
- session: {
46
- id: string;
47
- expiresAt: Date;
48
- [key: string]: unknown;
49
- };
92
+ user: AuthUser;
93
+ session: AuthSessionRecord;
94
+ }
95
+ /**
96
+ * Sign-up / sign-in response (contains token + user)
97
+ */
98
+ interface AuthResponse {
99
+ token: string;
100
+ user: AuthUser;
101
+ [key: string]: unknown;
50
102
  }
51
103
 
52
104
  /**
53
- * KrutAuth - Authentication client for KrutAI
105
+ * KrutAuth — fetch-based authentication client for KrutAI
54
106
  *
55
- * This class wraps Better Auth and adds API key validation
56
- * to ensure only authorized users can access authentication features.
107
+ * Calls your deployed server's `/lib-auth` routes for all auth operations.
108
+ * The API key is validated against the server before use.
57
109
  *
58
110
  * @example
59
111
  * ```typescript
60
112
  * import { KrutAuth } from '@krutai/auth';
61
113
  *
62
114
  * const auth = new KrutAuth({
63
- * apiKey: 'your-api-key-here',
64
- * betterAuthOptions: {
65
- * // Better Auth configuration
66
- * }
115
+ * apiKey: process.env.KRUTAI_API_KEY!,
116
+ * serverUrl: 'https://krut.ai',
67
117
  * });
68
118
  *
69
- * // Initialize the client (validates API key)
70
- * await auth.initialize();
119
+ * await auth.initialize(); // validates key against server
71
120
  *
72
- * // Use authentication features
73
- * const betterAuth = auth.getBetterAuth();
121
+ * // Sign up
122
+ * const { token, user } = await auth.signUpEmail({
123
+ * email: 'user@example.com',
124
+ * password: 'secret123',
125
+ * name: 'Alice',
126
+ * });
127
+ *
128
+ * // Sign in
129
+ * const result = await auth.signInEmail({
130
+ * email: 'user@example.com',
131
+ * password: 'secret123',
132
+ * });
133
+ *
134
+ * // Get session
135
+ * const session = await auth.getSession(result.token);
74
136
  * ```
75
137
  */
76
138
  declare class KrutAuth {
77
- private config;
78
- private apiKey;
79
- private betterAuthInstance;
139
+ private readonly apiKey;
140
+ private readonly serverUrl;
141
+ private readonly authPrefix;
142
+ private readonly config;
80
143
  private initialized;
81
- /**
82
- * Creates a new KrutAuth instance
83
- * @param config - Configuration options
84
- * @throws {ApiKeyValidationError} If API key is invalid
85
- */
86
144
  constructor(config: KrutAuthConfig);
87
145
  /**
88
- * Initialize the authentication client
89
- * Validates the API key and sets up Better Auth
90
- * @throws {ApiKeyValidationError} If API key validation fails
146
+ * Initialize the auth client.
147
+ * Validates the API key against the server, then marks client as ready.
148
+ *
149
+ * @throws {KrutAuthKeyValidationError} if the key is rejected or the server is unreachable
91
150
  */
92
151
  initialize(): Promise<void>;
93
152
  /**
94
- * Initialize Better Auth instance
95
- * @private
153
+ * Returns whether the client has been initialized.
96
154
  */
97
- private initializeBetterAuth;
155
+ isInitialized(): boolean;
156
+ private assertInitialized;
157
+ /** Common request headers sent to the server on every auth call. */
158
+ private authHeaders;
98
159
  /**
99
- * Get the Better Auth instance
100
- * @throws {Error} If not initialized
160
+ * Build the full URL for an auth endpoint.
161
+ * @param path - The better-auth sub-path, e.g. `/api/auth/sign-up/email`
101
162
  */
102
- getBetterAuth(): Auth;
163
+ private url;
103
164
  /**
104
- * Check if the client is initialized
165
+ * Generic request helper for any better-auth endpoint.
166
+ *
167
+ * Use this to call endpoints not covered by the convenience methods.
168
+ *
169
+ * @param method - HTTP method (GET, POST, etc.)
170
+ * @param path - The better-auth endpoint path (e.g. `/api/auth/sign-up/email`)
171
+ * @param body - Optional JSON body
172
+ * @returns The parsed JSON response
105
173
  */
106
- isInitialized(): boolean;
174
+ request<T = unknown>(method: string, path: string, body?: Record<string, unknown> | object): Promise<T>;
107
175
  /**
108
- * Get the API key (useful for making authenticated requests)
109
- * @returns The API key
176
+ * Sign up a new user with email and password.
177
+ *
178
+ * Calls: POST {serverUrl}/lib-auth/api/auth/sign-up/email
179
+ *
180
+ * @param params - Sign-up parameters (email, password, name)
181
+ * @returns The auth response containing token and user
110
182
  */
111
- getApiKey(): string;
183
+ signUpEmail(params: SignUpEmailParams): Promise<AuthResponse>;
112
184
  /**
113
- * Sign in a user
114
- * This is a convenience method that wraps Better Auth
115
- * You can access the full Better Auth API via getBetterAuth()
185
+ * Sign in with email and password.
186
+ *
187
+ * Calls: POST {serverUrl}/lib-auth/api/auth/sign-in/email
188
+ *
189
+ * @param params - Sign-in parameters (email, password)
190
+ * @returns The auth response containing token and user
116
191
  */
117
- signIn(): Promise<Auth>;
192
+ signInEmail(params: SignInEmailParams): Promise<AuthResponse>;
118
193
  /**
119
- * Sign out the current user
120
- * You can access the full Better Auth API via getBetterAuth()
194
+ * Get the current session for a user.
195
+ *
196
+ * Calls: GET {serverUrl}/lib-auth/api/auth/get-session
197
+ *
198
+ * @param sessionToken - The session token (Bearer token from sign-in)
199
+ * @returns The session containing user and session data
121
200
  */
122
- signOut(): Promise<Auth>;
201
+ getSession(sessionToken: string): Promise<AuthSession>;
123
202
  /**
124
- * Get the current session
125
- * You can access the full Better Auth API via getBetterAuth()
203
+ * Sign out the current user.
204
+ *
205
+ * Calls: POST {serverUrl}/lib-auth/api/auth/sign-out
206
+ *
207
+ * @param sessionToken - The session token to invalidate
126
208
  */
127
- getSession(): Promise<Auth>;
209
+ signOut(sessionToken: string): Promise<void>;
128
210
  }
129
211
 
130
212
  /**
131
- * krutAuthdrop-in replacement for betterAuth.
213
+ * @krutai/authAuthentication package for KrutAI
132
214
  *
133
- * Use this instead of importing betterAuth directly.
215
+ * A fetch-based wrapper that calls your deployed server's `/lib-auth` routes.
216
+ * The user's API key is validated against the server before any auth call is made.
134
217
  *
135
- * @example
218
+ * @example Basic usage
136
219
  * ```typescript
137
- * import { krutAuth } from "@krutai/auth";
138
- * import Database from "better-sqlite3";
220
+ * import { krutAuth } from '@krutai/auth';
139
221
  *
140
- * export const auth = krutAuth({
141
- * database: new Database("./sqlite.db"),
142
- * emailAndPassword: { enabled: true },
222
+ * const auth = krutAuth({
223
+ * apiKey: process.env.KRUTAI_API_KEY!,
224
+ * serverUrl: 'https://krut.ai',
225
+ * });
226
+ *
227
+ * await auth.initialize(); // validates key with server
228
+ *
229
+ * const { token, user } = await auth.signUpEmail({
230
+ * email: 'user@example.com',
231
+ * password: 'secret123',
232
+ * name: 'Alice',
143
233
  * });
144
234
  * ```
235
+ *
236
+ * @example Sign in
237
+ * ```typescript
238
+ * const auth = krutAuth({
239
+ * apiKey: process.env.KRUTAI_API_KEY!,
240
+ * serverUrl: 'https://krut.ai',
241
+ * });
242
+ * await auth.initialize();
243
+ *
244
+ * const { token, user } = await auth.signInEmail({
245
+ * email: 'user@example.com',
246
+ * password: 'secret123',
247
+ * });
248
+ * ```
249
+ *
250
+ * @packageDocumentation
145
251
  */
146
- declare function krutAuth(options: BetterAuthOptions): better_auth.Auth<BetterAuthOptions>;
147
252
 
148
- declare const VERSION = "0.1.9";
253
+ /**
254
+ * krutAuth — convenience factory.
255
+ *
256
+ * Creates a `KrutAuth` instance configured to call your server's `/lib-auth` routes.
257
+ *
258
+ * @param config - Auth configuration (`apiKey` and `serverUrl` are required)
259
+ * @returns A `KrutAuth` instance — call `.initialize()` before use
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * import { krutAuth } from '@krutai/auth';
264
+ *
265
+ * const auth = krutAuth({
266
+ * apiKey: process.env.KRUTAI_API_KEY!,
267
+ * serverUrl: 'https://krut.ai',
268
+ * });
269
+ *
270
+ * await auth.initialize();
271
+ * const { token, user } = await auth.signInEmail({
272
+ * email: 'user@example.com',
273
+ * password: 'secret123',
274
+ * });
275
+ * ```
276
+ */
277
+ declare function krutAuth(config: KrutAuthConfig): KrutAuth;
278
+ declare const VERSION = "0.4.0";
149
279
 
150
- export { type AuthSession, KrutAuth, type KrutAuthConfig, VERSION, krutAuth };
280
+ export { type AuthResponse, type AuthSession, type AuthSessionRecord, type AuthUser, DEFAULT_AUTH_PREFIX, DEFAULT_SERVER_URL, KrutAuth, type KrutAuthConfig, type SignInEmailParams, type SignUpEmailParams, VERSION, krutAuth };
package/dist/index.js CHANGED
@@ -1,116 +1,204 @@
1
1
  'use strict';
2
2
 
3
- var betterAuth = require('better-auth');
4
3
  var krutai = require('krutai');
5
4
 
6
- // src/index.ts
5
+ // src/types.ts
6
+ var DEFAULT_SERVER_URL = "http://localhost:8000";
7
+ var DEFAULT_AUTH_PREFIX = "/lib-auth";
7
8
  var KrutAuth = class {
8
- /**
9
- * Creates a new KrutAuth instance
10
- * @param config - Configuration options
11
- * @throws {ApiKeyValidationError} If API key is invalid
12
- */
9
+ apiKey;
10
+ serverUrl;
11
+ authPrefix;
12
+ config;
13
+ initialized = false;
13
14
  constructor(config) {
14
15
  this.config = config;
15
- const key = config.apiKey || process.env.KRUTAI_API_KEY || "";
16
- krutai.validateApiKeyFormat(key);
17
- this.apiKey = key;
16
+ this.apiKey = config.apiKey || process.env.KRUTAI_API_KEY || "";
17
+ this.serverUrl = (config.serverUrl ?? DEFAULT_SERVER_URL).replace(/\/$/, "");
18
+ this.authPrefix = (config.authPrefix ?? DEFAULT_AUTH_PREFIX).replace(/\/$/, "");
19
+ krutai.validateApiKeyFormat(this.apiKey);
18
20
  if (config.validateOnInit === false) {
19
- this.initializeBetterAuth();
21
+ this.initialized = true;
20
22
  }
21
23
  }
22
- apiKey;
23
- betterAuthInstance = null;
24
- initialized = false;
25
24
  /**
26
- * Initialize the authentication client
27
- * Validates the API key and sets up Better Auth
28
- * @throws {ApiKeyValidationError} If API key validation fails
25
+ * Initialize the auth client.
26
+ * Validates the API key against the server, then marks client as ready.
27
+ *
28
+ * @throws {KrutAuthKeyValidationError} if the key is rejected or the server is unreachable
29
29
  */
30
30
  async initialize() {
31
- if (this.initialized) {
32
- return;
33
- }
31
+ if (this.initialized) return;
34
32
  if (this.config.validateOnInit !== false) {
35
- await krutai.validateApiKeyWithService(this.apiKey, this.config.serverUrl);
33
+ await krutai.validateApiKeyWithService(this.apiKey, this.serverUrl);
36
34
  }
37
- this.initializeBetterAuth();
38
35
  this.initialized = true;
39
36
  }
40
37
  /**
41
- * Initialize Better Auth instance
42
- * @private
38
+ * Returns whether the client has been initialized.
43
39
  */
44
- initializeBetterAuth() {
45
- this.betterAuthInstance = betterAuth.betterAuth({
46
- ...this.config.betterAuthOptions
47
- });
40
+ isInitialized() {
41
+ return this.initialized;
48
42
  }
49
- /**
50
- * Get the Better Auth instance
51
- * @throws {Error} If not initialized
52
- */
53
- getBetterAuth() {
54
- if (!this.betterAuthInstance) {
43
+ // ---------------------------------------------------------------------------
44
+ // Private helpers
45
+ // ---------------------------------------------------------------------------
46
+ assertInitialized() {
47
+ if (!this.initialized) {
55
48
  throw new Error(
56
49
  "KrutAuth not initialized. Call initialize() first or set validateOnInit to false."
57
50
  );
58
51
  }
59
- return this.betterAuthInstance;
52
+ }
53
+ /** Common request headers sent to the server on every auth call. */
54
+ authHeaders() {
55
+ return {
56
+ "Content-Type": "application/json",
57
+ Authorization: `Bearer ${this.apiKey}`,
58
+ "x-api-key": this.apiKey
59
+ };
60
60
  }
61
61
  /**
62
- * Check if the client is initialized
62
+ * Build the full URL for an auth endpoint.
63
+ * @param path - The better-auth sub-path, e.g. `/api/auth/sign-up/email`
63
64
  */
64
- isInitialized() {
65
- return this.initialized;
65
+ url(path) {
66
+ const cleanPath = path.startsWith("/") ? path : `/${path}`;
67
+ return `${this.serverUrl}${this.authPrefix}${cleanPath}`;
66
68
  }
69
+ // ---------------------------------------------------------------------------
70
+ // Public Auth Methods
71
+ // ---------------------------------------------------------------------------
67
72
  /**
68
- * Get the API key (useful for making authenticated requests)
69
- * @returns The API key
73
+ * Generic request helper for any better-auth endpoint.
74
+ *
75
+ * Use this to call endpoints not covered by the convenience methods.
76
+ *
77
+ * @param method - HTTP method (GET, POST, etc.)
78
+ * @param path - The better-auth endpoint path (e.g. `/api/auth/sign-up/email`)
79
+ * @param body - Optional JSON body
80
+ * @returns The parsed JSON response
70
81
  */
71
- getApiKey() {
72
- return this.apiKey;
82
+ async request(method, path, body) {
83
+ this.assertInitialized();
84
+ const options = {
85
+ method,
86
+ headers: this.authHeaders()
87
+ };
88
+ if (body && method !== "GET") {
89
+ options.body = JSON.stringify(body);
90
+ }
91
+ const response = await fetch(this.url(path), options);
92
+ if (!response.ok) {
93
+ let errorMessage = `Auth server returned HTTP ${response.status} for ${path}`;
94
+ try {
95
+ const errorData = await response.json();
96
+ if (errorData?.error) errorMessage = errorData.error;
97
+ else if (errorData?.message) errorMessage = errorData.message;
98
+ } catch {
99
+ }
100
+ throw new Error(errorMessage);
101
+ }
102
+ return await response.json();
73
103
  }
74
104
  /**
75
- * Sign in a user
76
- * This is a convenience method that wraps Better Auth
77
- * You can access the full Better Auth API via getBetterAuth()
105
+ * Sign up a new user with email and password.
106
+ *
107
+ * Calls: POST {serverUrl}/lib-auth/api/auth/sign-up/email
108
+ *
109
+ * @param params - Sign-up parameters (email, password, name)
110
+ * @returns The auth response containing token and user
78
111
  */
79
- async signIn() {
80
- return this.getBetterAuth();
112
+ async signUpEmail(params) {
113
+ return this.request("POST", "/api/auth/sign-up/email", params);
81
114
  }
82
115
  /**
83
- * Sign out the current user
84
- * You can access the full Better Auth API via getBetterAuth()
116
+ * Sign in with email and password.
117
+ *
118
+ * Calls: POST {serverUrl}/lib-auth/api/auth/sign-in/email
119
+ *
120
+ * @param params - Sign-in parameters (email, password)
121
+ * @returns The auth response containing token and user
85
122
  */
86
- async signOut() {
87
- return this.getBetterAuth();
123
+ async signInEmail(params) {
124
+ return this.request("POST", "/api/auth/sign-in/email", params);
88
125
  }
89
126
  /**
90
- * Get the current session
91
- * You can access the full Better Auth API via getBetterAuth()
127
+ * Get the current session for a user.
128
+ *
129
+ * Calls: GET {serverUrl}/lib-auth/api/auth/get-session
130
+ *
131
+ * @param sessionToken - The session token (Bearer token from sign-in)
132
+ * @returns The session containing user and session data
92
133
  */
93
- async getSession() {
94
- return this.getBetterAuth();
134
+ async getSession(sessionToken) {
135
+ this.assertInitialized();
136
+ const response = await fetch(this.url("/api/auth/get-session"), {
137
+ method: "GET",
138
+ headers: {
139
+ ...this.authHeaders(),
140
+ Cookie: `better-auth.session_token=${sessionToken}`
141
+ }
142
+ });
143
+ if (!response.ok) {
144
+ let errorMessage = `Auth server returned HTTP ${response.status} for /api/auth/get-session`;
145
+ try {
146
+ const errorData = await response.json();
147
+ if (errorData?.error) errorMessage = errorData.error;
148
+ else if (errorData?.message) errorMessage = errorData.message;
149
+ } catch {
150
+ }
151
+ throw new Error(errorMessage);
152
+ }
153
+ return await response.json();
154
+ }
155
+ /**
156
+ * Sign out the current user.
157
+ *
158
+ * Calls: POST {serverUrl}/lib-auth/api/auth/sign-out
159
+ *
160
+ * @param sessionToken - The session token to invalidate
161
+ */
162
+ async signOut(sessionToken) {
163
+ this.assertInitialized();
164
+ const response = await fetch(this.url("/api/auth/sign-out"), {
165
+ method: "POST",
166
+ headers: {
167
+ ...this.authHeaders(),
168
+ Cookie: `better-auth.session_token=${sessionToken}`
169
+ }
170
+ });
171
+ if (!response.ok) {
172
+ let errorMessage = `Auth server returned HTTP ${response.status} for /api/auth/sign-out`;
173
+ try {
174
+ const errorData = await response.json();
175
+ if (errorData?.error) errorMessage = errorData.error;
176
+ else if (errorData?.message) errorMessage = errorData.message;
177
+ } catch {
178
+ }
179
+ throw new Error(errorMessage);
180
+ }
95
181
  }
96
182
  };
97
- function krutAuth(options) {
98
- return betterAuth.betterAuth(options);
183
+ function krutAuth(config) {
184
+ return new KrutAuth(config);
99
185
  }
100
- var VERSION = "0.1.9";
186
+ var VERSION = "0.4.0";
101
187
 
102
- Object.defineProperty(exports, "ApiKeyValidationError", {
188
+ Object.defineProperty(exports, "KrutAuthKeyValidationError", {
103
189
  enumerable: true,
104
190
  get: function () { return krutai.ApiKeyValidationError; }
105
191
  });
106
- Object.defineProperty(exports, "validateApiKeyFormat", {
192
+ Object.defineProperty(exports, "validateApiKey", {
107
193
  enumerable: true,
108
- get: function () { return krutai.validateApiKeyFormat; }
194
+ get: function () { return krutai.validateApiKeyWithService; }
109
195
  });
110
- Object.defineProperty(exports, "validateApiKeyWithService", {
196
+ Object.defineProperty(exports, "validateApiKeyFormat", {
111
197
  enumerable: true,
112
- get: function () { return krutai.validateApiKeyWithService; }
198
+ get: function () { return krutai.validateApiKeyFormat; }
113
199
  });
200
+ exports.DEFAULT_AUTH_PREFIX = DEFAULT_AUTH_PREFIX;
201
+ exports.DEFAULT_SERVER_URL = DEFAULT_SERVER_URL;
114
202
  exports.KrutAuth = KrutAuth;
115
203
  exports.VERSION = VERSION;
116
204
  exports.krutAuth = krutAuth;