@auth-gate/core 0.1.0 → 0.4.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.
- package/README.md +210 -0
- package/dist/index.cjs +2 -8
- package/dist/index.d.cts +0 -8
- package/dist/index.d.ts +0 -8
- package/dist/index.mjs +2 -8
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# @auth-gate/core
|
|
2
|
+
|
|
3
|
+
Core client library for [AuthGate](https://authgate.dev) — the OAuth proxy that handles provider configuration, token exchange, and user normalization so you don't have to.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @auth-gate/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createAuthGateClient } from "@auth-gate/core";
|
|
15
|
+
|
|
16
|
+
const client = createAuthGateClient({
|
|
17
|
+
apiKey: process.env.AUTHGATE_API_KEY!,
|
|
18
|
+
projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
19
|
+
baseUrl: "https://authgate.dev", // or your self-hosted instance
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
### OAuth Authentication
|
|
26
|
+
|
|
27
|
+
Supports Google, GitHub, Discord, Azure (Microsoft), and Apple.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
// Generate the authorization URL
|
|
31
|
+
const url = client.getOAuthUrl("google", "https://yourapp.com/auth/callback");
|
|
32
|
+
|
|
33
|
+
// After callback, verify the JWT token from AuthGate
|
|
34
|
+
const result = await client.verifyToken(token);
|
|
35
|
+
if (result.valid) {
|
|
36
|
+
console.log(result.user); // { id, email, name, picture, provider }
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Session Encryption
|
|
41
|
+
|
|
42
|
+
Sessions are encrypted with AES-256-GCM using keys derived via HKDF-SHA256.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
// Encrypt a user into a session cookie value
|
|
46
|
+
const cookieValue = await client.encryptSession(user);
|
|
47
|
+
|
|
48
|
+
// Decrypt a session cookie back to a user
|
|
49
|
+
const user = await client.decryptSession(cookieValue);
|
|
50
|
+
|
|
51
|
+
// Get full payload with timestamps
|
|
52
|
+
const payload = await client.decryptSessionPayload(cookieValue);
|
|
53
|
+
// { user, iat, exp }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### CSRF / OAuth State
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// Before redirect: create state + nonce
|
|
60
|
+
const { state, nonce } = await client.createState();
|
|
61
|
+
// Store nonce in a cookie, pass state in the OAuth URL
|
|
62
|
+
|
|
63
|
+
// After callback: verify state against nonce
|
|
64
|
+
const valid = await client.verifyState(state, nonce);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Email Authentication
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
// Sign up
|
|
71
|
+
await client.emailSignup({ email, password, name });
|
|
72
|
+
|
|
73
|
+
// Sign in
|
|
74
|
+
const result = await client.emailSignin({ email, password });
|
|
75
|
+
|
|
76
|
+
// Verify email with OTP code
|
|
77
|
+
await client.emailVerifyCode({ email, code });
|
|
78
|
+
|
|
79
|
+
// Password reset
|
|
80
|
+
await client.emailForgotPassword({ email });
|
|
81
|
+
await client.emailResetPassword({ token, password });
|
|
82
|
+
|
|
83
|
+
// Magic link
|
|
84
|
+
await client.magicLinkSend({ email, callbackUrl });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### SMS Authentication
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// Send verification code
|
|
91
|
+
await client.smsSendCode({ phone }); // E.164 format: +15551234567
|
|
92
|
+
|
|
93
|
+
// Verify code
|
|
94
|
+
const result = await client.smsVerifyCode({ phone, code });
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Multi-Factor Authentication (MFA)
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
// TOTP setup
|
|
101
|
+
const setup = await client.mfaTotpSetup(jwt);
|
|
102
|
+
// { secret, qr_code, uri }
|
|
103
|
+
|
|
104
|
+
// Verify TOTP setup
|
|
105
|
+
await client.mfaTotpVerifySetup(jwt, { code });
|
|
106
|
+
|
|
107
|
+
// Complete MFA challenge during sign-in
|
|
108
|
+
const result = await client.mfaVerify({ mfa_challenge, code, method: "totp" });
|
|
109
|
+
|
|
110
|
+
// SMS-based MFA
|
|
111
|
+
await client.mfaSmsSendCode({ mfa_challenge });
|
|
112
|
+
await client.mfaVerify({ mfa_challenge, code, method: "sms" });
|
|
113
|
+
|
|
114
|
+
// Backup codes
|
|
115
|
+
const codes = await client.mfaBackupCodesGenerate(jwt);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Session Management
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
// Refresh an expired token
|
|
122
|
+
const result = await client.refreshToken(refreshToken);
|
|
123
|
+
|
|
124
|
+
// Revoke a session
|
|
125
|
+
await client.revokeSession(refreshToken);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Cookie Helpers
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
client.cookieName; // "__authgate"
|
|
132
|
+
client.nonceCookieName; // "__authgate_nonce"
|
|
133
|
+
client.refreshTokenCookieName; // "__authgate_refresh"
|
|
134
|
+
client.sessionMaxAge; // 604800 (7 days)
|
|
135
|
+
|
|
136
|
+
client.getSessionCookieOptions();
|
|
137
|
+
// { httpOnly: true, secure: true, sameSite: "lax", maxAge: 604800, path: "/" }
|
|
138
|
+
|
|
139
|
+
client.getNonceCookieOptions();
|
|
140
|
+
// { httpOnly: true, secure: true, sameSite: "lax", maxAge: 600, path: "/" }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Configuration
|
|
144
|
+
|
|
145
|
+
| Option | Type | Required | Description |
|
|
146
|
+
|--------|------|----------|-------------|
|
|
147
|
+
| `apiKey` | `string` | Yes | Your AuthGate API key |
|
|
148
|
+
| `projectId` | `string` | Yes | Your AuthGate project ID |
|
|
149
|
+
| `baseUrl` | `string` | Yes | AuthGate instance URL |
|
|
150
|
+
| `cookieName` | `string` | No | Session cookie name (default: `__authgate`) |
|
|
151
|
+
| `sessionMaxAge` | `number` | No | Session TTL in seconds (default: `604800` / 7 days) |
|
|
152
|
+
| `callbackPath` | `string` | No | OAuth callback path (default: `/api/auth/callback`) |
|
|
153
|
+
|
|
154
|
+
## Types
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import type {
|
|
158
|
+
AuthGateUser,
|
|
159
|
+
AuthGateConfig,
|
|
160
|
+
OAuthProvider,
|
|
161
|
+
TokenVerifyResult,
|
|
162
|
+
SessionPayload,
|
|
163
|
+
CookieOptions,
|
|
164
|
+
MfaChallengeResponse,
|
|
165
|
+
MfaStatus,
|
|
166
|
+
TotpSetupResponse,
|
|
167
|
+
BackupCodesResponse,
|
|
168
|
+
} from "@auth-gate/core";
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### `AuthGateUser`
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
interface AuthGateUser {
|
|
175
|
+
id: string;
|
|
176
|
+
email: string;
|
|
177
|
+
phone?: string;
|
|
178
|
+
name?: string;
|
|
179
|
+
picture?: string;
|
|
180
|
+
provider: string;
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### `OAuthProvider`
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
type OAuthProvider = "google" | "github" | "discord" | "azure" | "apple";
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Error Handling
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import {
|
|
194
|
+
AuthGateError,
|
|
195
|
+
TokenVerificationError,
|
|
196
|
+
SessionDecryptionError,
|
|
197
|
+
InvalidStateError,
|
|
198
|
+
} from "@auth-gate/core";
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Framework SDKs
|
|
202
|
+
|
|
203
|
+
For framework-specific integrations with built-in route handlers, session helpers, and middleware:
|
|
204
|
+
|
|
205
|
+
- **Next.js** — [`@auth-gate/nextjs`](https://www.npmjs.com/package/@auth-gate/nextjs)
|
|
206
|
+
- **React + Hono** — [`@auth-gate/react`](https://www.npmjs.com/package/@auth-gate/react)
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -301,17 +301,11 @@ var InvalidStateError = class extends AuthGateError {
|
|
|
301
301
|
var AuthGateClient = class {
|
|
302
302
|
/**
|
|
303
303
|
* @param config - Client configuration. See {@link AuthGateConfig}.
|
|
304
|
-
* @throws {@link AuthGateError} if `sessionSecret` is shorter than 32 characters.
|
|
305
304
|
*/
|
|
306
305
|
constructor(config) {
|
|
307
306
|
this.encryptionKey = null;
|
|
308
307
|
this.stateKey = null;
|
|
309
308
|
var _a, _b, _c;
|
|
310
|
-
if (!config.sessionSecret || config.sessionSecret.length < 32) {
|
|
311
|
-
throw new AuthGateError(
|
|
312
|
-
"sessionSecret must be at least 32 characters long"
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
309
|
this.config = __spreadProps(__spreadValues({}, config), {
|
|
316
310
|
cookieName: (_a = config.cookieName) != null ? _a : DEFAULT_COOKIE_NAME,
|
|
317
311
|
sessionMaxAge: (_b = config.sessionMaxAge) != null ? _b : SESSION_MAX_AGE,
|
|
@@ -321,8 +315,8 @@ var AuthGateClient = class {
|
|
|
321
315
|
}
|
|
322
316
|
async deriveKeys() {
|
|
323
317
|
const [encKey, stKey] = await Promise.all([
|
|
324
|
-
deriveEncryptionKey(this.config.
|
|
325
|
-
deriveStateKey(this.config.
|
|
318
|
+
deriveEncryptionKey(this.config.apiKey),
|
|
319
|
+
deriveStateKey(this.config.apiKey)
|
|
326
320
|
]);
|
|
327
321
|
this.encryptionKey = encKey;
|
|
328
322
|
this.stateKey = stKey;
|
package/dist/index.d.cts
CHANGED
|
@@ -49,7 +49,6 @@ interface TokenVerifyResult {
|
|
|
49
49
|
* apiKey: process.env.AUTHGATE_API_KEY!,
|
|
50
50
|
* projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
51
51
|
* baseUrl: "https://authgate.dev",
|
|
52
|
-
* sessionSecret: process.env.SESSION_SECRET!, // min 32 chars
|
|
53
52
|
* });
|
|
54
53
|
* ```
|
|
55
54
|
*/
|
|
@@ -60,11 +59,6 @@ interface AuthGateConfig {
|
|
|
60
59
|
projectId: string;
|
|
61
60
|
/** Base URL of the AuthGate service (e.g. `"https://authgate.dev"`). */
|
|
62
61
|
baseUrl: string;
|
|
63
|
-
/**
|
|
64
|
-
* Secret used to derive encryption keys for session cookies and OAuth state.
|
|
65
|
-
* Must be at least 32 characters. Use a cryptographically random string.
|
|
66
|
-
*/
|
|
67
|
-
sessionSecret: string;
|
|
68
62
|
/**
|
|
69
63
|
* Name of the session cookie.
|
|
70
64
|
* @defaultValue `"__authgate"`
|
|
@@ -180,7 +174,6 @@ interface BackupCodesResponse {
|
|
|
180
174
|
* apiKey: process.env.AUTHGATE_API_KEY!,
|
|
181
175
|
* projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
182
176
|
* baseUrl: "https://authgate.dev",
|
|
183
|
-
* sessionSecret: process.env.SESSION_SECRET!,
|
|
184
177
|
* });
|
|
185
178
|
* ```
|
|
186
179
|
*/
|
|
@@ -191,7 +184,6 @@ declare class AuthGateClient {
|
|
|
191
184
|
private keysReady;
|
|
192
185
|
/**
|
|
193
186
|
* @param config - Client configuration. See {@link AuthGateConfig}.
|
|
194
|
-
* @throws {@link AuthGateError} if `sessionSecret` is shorter than 32 characters.
|
|
195
187
|
*/
|
|
196
188
|
constructor(config: AuthGateConfig);
|
|
197
189
|
private deriveKeys;
|
package/dist/index.d.ts
CHANGED
|
@@ -49,7 +49,6 @@ interface TokenVerifyResult {
|
|
|
49
49
|
* apiKey: process.env.AUTHGATE_API_KEY!,
|
|
50
50
|
* projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
51
51
|
* baseUrl: "https://authgate.dev",
|
|
52
|
-
* sessionSecret: process.env.SESSION_SECRET!, // min 32 chars
|
|
53
52
|
* });
|
|
54
53
|
* ```
|
|
55
54
|
*/
|
|
@@ -60,11 +59,6 @@ interface AuthGateConfig {
|
|
|
60
59
|
projectId: string;
|
|
61
60
|
/** Base URL of the AuthGate service (e.g. `"https://authgate.dev"`). */
|
|
62
61
|
baseUrl: string;
|
|
63
|
-
/**
|
|
64
|
-
* Secret used to derive encryption keys for session cookies and OAuth state.
|
|
65
|
-
* Must be at least 32 characters. Use a cryptographically random string.
|
|
66
|
-
*/
|
|
67
|
-
sessionSecret: string;
|
|
68
62
|
/**
|
|
69
63
|
* Name of the session cookie.
|
|
70
64
|
* @defaultValue `"__authgate"`
|
|
@@ -180,7 +174,6 @@ interface BackupCodesResponse {
|
|
|
180
174
|
* apiKey: process.env.AUTHGATE_API_KEY!,
|
|
181
175
|
* projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
182
176
|
* baseUrl: "https://authgate.dev",
|
|
183
|
-
* sessionSecret: process.env.SESSION_SECRET!,
|
|
184
177
|
* });
|
|
185
178
|
* ```
|
|
186
179
|
*/
|
|
@@ -191,7 +184,6 @@ declare class AuthGateClient {
|
|
|
191
184
|
private keysReady;
|
|
192
185
|
/**
|
|
193
186
|
* @param config - Client configuration. See {@link AuthGateConfig}.
|
|
194
|
-
* @throws {@link AuthGateError} if `sessionSecret` is shorter than 32 characters.
|
|
195
187
|
*/
|
|
196
188
|
constructor(config: AuthGateConfig);
|
|
197
189
|
private deriveKeys;
|
package/dist/index.mjs
CHANGED
|
@@ -267,17 +267,11 @@ var InvalidStateError = class extends AuthGateError {
|
|
|
267
267
|
var AuthGateClient = class {
|
|
268
268
|
/**
|
|
269
269
|
* @param config - Client configuration. See {@link AuthGateConfig}.
|
|
270
|
-
* @throws {@link AuthGateError} if `sessionSecret` is shorter than 32 characters.
|
|
271
270
|
*/
|
|
272
271
|
constructor(config) {
|
|
273
272
|
this.encryptionKey = null;
|
|
274
273
|
this.stateKey = null;
|
|
275
274
|
var _a, _b, _c;
|
|
276
|
-
if (!config.sessionSecret || config.sessionSecret.length < 32) {
|
|
277
|
-
throw new AuthGateError(
|
|
278
|
-
"sessionSecret must be at least 32 characters long"
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
275
|
this.config = __spreadProps(__spreadValues({}, config), {
|
|
282
276
|
cookieName: (_a = config.cookieName) != null ? _a : DEFAULT_COOKIE_NAME,
|
|
283
277
|
sessionMaxAge: (_b = config.sessionMaxAge) != null ? _b : SESSION_MAX_AGE,
|
|
@@ -287,8 +281,8 @@ var AuthGateClient = class {
|
|
|
287
281
|
}
|
|
288
282
|
async deriveKeys() {
|
|
289
283
|
const [encKey, stKey] = await Promise.all([
|
|
290
|
-
deriveEncryptionKey(this.config.
|
|
291
|
-
deriveStateKey(this.config.
|
|
284
|
+
deriveEncryptionKey(this.config.apiKey),
|
|
285
|
+
deriveStateKey(this.config.apiKey)
|
|
292
286
|
]);
|
|
293
287
|
this.encryptionKey = encKey;
|
|
294
288
|
this.stateKey = stKey;
|