@auth-gate/core 0.4.0 → 0.6.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 +3 -5
- package/dist/index.cjs +168 -45
- package/dist/index.d.cts +90 -9
- package/dist/index.d.ts +90 -9
- package/dist/index.mjs +168 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,6 @@ import { createAuthGateClient } from "@auth-gate/core";
|
|
|
15
15
|
|
|
16
16
|
const client = createAuthGateClient({
|
|
17
17
|
apiKey: process.env.AUTHGATE_API_KEY!,
|
|
18
|
-
projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
19
18
|
baseUrl: "https://authgate.dev", // or your self-hosted instance
|
|
20
19
|
});
|
|
21
20
|
```
|
|
@@ -27,8 +26,8 @@ const client = createAuthGateClient({
|
|
|
27
26
|
Supports Google, GitHub, Discord, Azure (Microsoft), and Apple.
|
|
28
27
|
|
|
29
28
|
```ts
|
|
30
|
-
// Generate the authorization URL
|
|
31
|
-
const url = client.getOAuthUrl("google", "https://yourapp.com/auth/callback");
|
|
29
|
+
// Generate the authorization URL (async — resolves project ID from API key)
|
|
30
|
+
const url = await client.getOAuthUrl("google", "https://yourapp.com/auth/callback");
|
|
32
31
|
|
|
33
32
|
// After callback, verify the JWT token from AuthGate
|
|
34
33
|
const result = await client.verifyToken(token);
|
|
@@ -144,8 +143,7 @@ client.getNonceCookieOptions();
|
|
|
144
143
|
|
|
145
144
|
| Option | Type | Required | Description |
|
|
146
145
|
|--------|------|----------|-------------|
|
|
147
|
-
| `apiKey` | `string` | Yes | Your AuthGate API key |
|
|
148
|
-
| `projectId` | `string` | Yes | Your AuthGate project ID |
|
|
146
|
+
| `apiKey` | `string` | Yes | Your AuthGate API key (also used to resolve project ID) |
|
|
149
147
|
| `baseUrl` | `string` | Yes | AuthGate instance URL |
|
|
150
148
|
| `cookieName` | `string` | No | Session cookie name (default: `__authgate`) |
|
|
151
149
|
| `sessionMaxAge` | `number` | No | Session TTL in seconds (default: `604800` / 7 days) |
|
package/dist/index.cjs
CHANGED
|
@@ -39,6 +39,7 @@ var index_exports = {};
|
|
|
39
39
|
__export(index_exports, {
|
|
40
40
|
AuthGateClient: () => AuthGateClient,
|
|
41
41
|
AuthGateError: () => AuthGateError,
|
|
42
|
+
ConfigurationError: () => ConfigurationError,
|
|
42
43
|
DEFAULT_COOKIE_NAME: () => DEFAULT_COOKIE_NAME,
|
|
43
44
|
InvalidStateError: () => InvalidStateError,
|
|
44
45
|
NONCE_COOKIE_NAME: () => NONCE_COOKIE_NAME,
|
|
@@ -48,7 +49,9 @@ __export(index_exports, {
|
|
|
48
49
|
SUPPORTED_PROVIDERS: () => SUPPORTED_PROVIDERS,
|
|
49
50
|
SessionDecryptionError: () => SessionDecryptionError,
|
|
50
51
|
TokenVerificationError: () => TokenVerificationError,
|
|
51
|
-
createAuthGateClient: () => createAuthGateClient
|
|
52
|
+
createAuthGateClient: () => createAuthGateClient,
|
|
53
|
+
hasFeature: () => hasFeature,
|
|
54
|
+
hasPlan: () => hasPlan
|
|
52
55
|
});
|
|
53
56
|
module.exports = __toCommonJS(index_exports);
|
|
54
57
|
|
|
@@ -296,6 +299,12 @@ var InvalidStateError = class extends AuthGateError {
|
|
|
296
299
|
this.name = "InvalidStateError";
|
|
297
300
|
}
|
|
298
301
|
};
|
|
302
|
+
var ConfigurationError = class extends AuthGateError {
|
|
303
|
+
constructor(message) {
|
|
304
|
+
super(message);
|
|
305
|
+
this.name = "ConfigurationError";
|
|
306
|
+
}
|
|
307
|
+
};
|
|
299
308
|
|
|
300
309
|
// src/client.ts
|
|
301
310
|
var AuthGateClient = class {
|
|
@@ -306,6 +315,28 @@ var AuthGateClient = class {
|
|
|
306
315
|
this.encryptionKey = null;
|
|
307
316
|
this.stateKey = null;
|
|
308
317
|
var _a, _b, _c;
|
|
318
|
+
if (!config.apiKey || typeof config.apiKey !== "string" || config.apiKey.trim() === "") {
|
|
319
|
+
throw new ConfigurationError(
|
|
320
|
+
"[AuthGate] Missing or empty `apiKey`. Get your API key from the AuthGate dashboard \u2192 Project \u2192 API Key."
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
if (!config.baseUrl || typeof config.baseUrl !== "string" || config.baseUrl.trim() === "") {
|
|
324
|
+
throw new ConfigurationError(
|
|
325
|
+
'[AuthGate] Missing or empty `baseUrl`. Set this to your AuthGate service URL (e.g. "https://authgate.dev").'
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
new URL(config.baseUrl);
|
|
330
|
+
} catch (e) {
|
|
331
|
+
throw new ConfigurationError(
|
|
332
|
+
`[AuthGate] Invalid \`baseUrl\`: "${config.baseUrl}". Must be a valid URL (e.g. "https://authgate.dev").`
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
if (config.callbackPath !== void 0 && !config.callbackPath.startsWith("/")) {
|
|
336
|
+
throw new ConfigurationError(
|
|
337
|
+
`[AuthGate] Invalid \`callbackPath\`: "${config.callbackPath}". Must start with "/" (e.g. "/api/auth/callback").`
|
|
338
|
+
);
|
|
339
|
+
}
|
|
309
340
|
this.config = __spreadProps(__spreadValues({}, config), {
|
|
310
341
|
cookieName: (_a = config.cookieName) != null ? _a : DEFAULT_COOKIE_NAME,
|
|
311
342
|
sessionMaxAge: (_b = config.sessionMaxAge) != null ? _b : SESSION_MAX_AGE,
|
|
@@ -453,17 +484,28 @@ var AuthGateClient = class {
|
|
|
453
484
|
* @returns The full authorization URL to redirect the user to.
|
|
454
485
|
* @throws {@link AuthGateError} if the provider is not in {@link SUPPORTED_PROVIDERS}.
|
|
455
486
|
*/
|
|
456
|
-
getOAuthUrl(provider, callbackUrl, options) {
|
|
487
|
+
async getOAuthUrl(provider, callbackUrl, options) {
|
|
457
488
|
if (!SUPPORTED_PROVIDERS.includes(provider)) {
|
|
458
489
|
throw new AuthGateError(`Unsupported provider: ${provider}`);
|
|
459
490
|
}
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
491
|
+
const response = await fetch(`${this.config.baseUrl}/api/proxy/${provider}`, {
|
|
492
|
+
method: "POST",
|
|
493
|
+
headers: {
|
|
494
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
495
|
+
"Content-Type": "application/json"
|
|
496
|
+
},
|
|
497
|
+
body: JSON.stringify({
|
|
498
|
+
callback_url: callbackUrl,
|
|
499
|
+
state: options == null ? void 0 : options.state,
|
|
500
|
+
link_to: options == null ? void 0 : options.linkTo
|
|
501
|
+
})
|
|
502
|
+
});
|
|
503
|
+
if (!response.ok) {
|
|
504
|
+
const error = await response.json().catch(() => ({}));
|
|
505
|
+
throw new AuthGateError(error.error || `OAuth initiation failed: ${response.status}`);
|
|
465
506
|
}
|
|
466
|
-
|
|
507
|
+
const data = await response.json();
|
|
508
|
+
return data.redirect_url;
|
|
467
509
|
}
|
|
468
510
|
// ---------------------------------------------------------------------------
|
|
469
511
|
// Email auth
|
|
@@ -477,12 +519,14 @@ var AuthGateClient = class {
|
|
|
477
519
|
async emailSignup(data) {
|
|
478
520
|
return fetch(`${this.config.baseUrl}/api/proxy/email/signup`, {
|
|
479
521
|
method: "POST",
|
|
480
|
-
headers: {
|
|
522
|
+
headers: {
|
|
523
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
524
|
+
"Content-Type": "application/json"
|
|
525
|
+
},
|
|
481
526
|
body: JSON.stringify({
|
|
482
527
|
email: data.email,
|
|
483
528
|
password: data.password,
|
|
484
529
|
name: data.name,
|
|
485
|
-
project_id: this.config.projectId,
|
|
486
530
|
callback_url: data.callbackUrl
|
|
487
531
|
})
|
|
488
532
|
});
|
|
@@ -499,11 +543,13 @@ var AuthGateClient = class {
|
|
|
499
543
|
async emailSignin(data) {
|
|
500
544
|
return fetch(`${this.config.baseUrl}/api/proxy/email/signin`, {
|
|
501
545
|
method: "POST",
|
|
502
|
-
headers: {
|
|
546
|
+
headers: {
|
|
547
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
548
|
+
"Content-Type": "application/json"
|
|
549
|
+
},
|
|
503
550
|
body: JSON.stringify({
|
|
504
551
|
email: data.email,
|
|
505
552
|
password: data.password,
|
|
506
|
-
project_id: this.config.projectId,
|
|
507
553
|
callback_url: data.callbackUrl
|
|
508
554
|
})
|
|
509
555
|
});
|
|
@@ -517,10 +563,12 @@ var AuthGateClient = class {
|
|
|
517
563
|
async emailForgotPassword(data) {
|
|
518
564
|
return fetch(`${this.config.baseUrl}/api/proxy/email/reset-password`, {
|
|
519
565
|
method: "POST",
|
|
520
|
-
headers: {
|
|
566
|
+
headers: {
|
|
567
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
568
|
+
"Content-Type": "application/json"
|
|
569
|
+
},
|
|
521
570
|
body: JSON.stringify({
|
|
522
571
|
email: data.email,
|
|
523
|
-
project_id: this.config.projectId,
|
|
524
572
|
callback_url: data.callbackUrl
|
|
525
573
|
})
|
|
526
574
|
});
|
|
@@ -536,11 +584,13 @@ var AuthGateClient = class {
|
|
|
536
584
|
`${this.config.baseUrl}/api/proxy/email/reset-password/confirm`,
|
|
537
585
|
{
|
|
538
586
|
method: "POST",
|
|
539
|
-
headers: {
|
|
587
|
+
headers: {
|
|
588
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
589
|
+
"Content-Type": "application/json"
|
|
590
|
+
},
|
|
540
591
|
body: JSON.stringify({
|
|
541
592
|
token: data.token,
|
|
542
|
-
password: data.password
|
|
543
|
-
project_id: this.config.projectId
|
|
593
|
+
password: data.password
|
|
544
594
|
})
|
|
545
595
|
}
|
|
546
596
|
);
|
|
@@ -559,10 +609,12 @@ var AuthGateClient = class {
|
|
|
559
609
|
`${this.config.baseUrl}/api/proxy/email/magic-link/send`,
|
|
560
610
|
{
|
|
561
611
|
method: "POST",
|
|
562
|
-
headers: {
|
|
612
|
+
headers: {
|
|
613
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
614
|
+
"Content-Type": "application/json"
|
|
615
|
+
},
|
|
563
616
|
body: JSON.stringify({
|
|
564
617
|
email: data.email,
|
|
565
|
-
project_id: this.config.projectId,
|
|
566
618
|
callback_url: data.callbackUrl
|
|
567
619
|
})
|
|
568
620
|
}
|
|
@@ -580,11 +632,13 @@ var AuthGateClient = class {
|
|
|
580
632
|
async emailVerifyCode(data) {
|
|
581
633
|
return fetch(`${this.config.baseUrl}/api/proxy/email/verify`, {
|
|
582
634
|
method: "POST",
|
|
583
|
-
headers: {
|
|
635
|
+
headers: {
|
|
636
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
637
|
+
"Content-Type": "application/json"
|
|
638
|
+
},
|
|
584
639
|
body: JSON.stringify({
|
|
585
640
|
email: data.email,
|
|
586
|
-
code: data.code
|
|
587
|
-
project_id: this.config.projectId
|
|
641
|
+
code: data.code
|
|
588
642
|
})
|
|
589
643
|
});
|
|
590
644
|
}
|
|
@@ -600,10 +654,12 @@ var AuthGateClient = class {
|
|
|
600
654
|
async smsSendCode(data) {
|
|
601
655
|
return fetch(`${this.config.baseUrl}/api/proxy/sms/send-code`, {
|
|
602
656
|
method: "POST",
|
|
603
|
-
headers: {
|
|
657
|
+
headers: {
|
|
658
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
659
|
+
"Content-Type": "application/json"
|
|
660
|
+
},
|
|
604
661
|
body: JSON.stringify({
|
|
605
662
|
phone: data.phone,
|
|
606
|
-
project_id: this.config.projectId,
|
|
607
663
|
callback_url: data.callbackUrl
|
|
608
664
|
})
|
|
609
665
|
});
|
|
@@ -617,11 +673,13 @@ var AuthGateClient = class {
|
|
|
617
673
|
async smsVerifyCode(data) {
|
|
618
674
|
return fetch(`${this.config.baseUrl}/api/proxy/sms/verify-code`, {
|
|
619
675
|
method: "POST",
|
|
620
|
-
headers: {
|
|
676
|
+
headers: {
|
|
677
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
678
|
+
"Content-Type": "application/json"
|
|
679
|
+
},
|
|
621
680
|
body: JSON.stringify({
|
|
622
681
|
phone: data.phone,
|
|
623
682
|
code: data.code,
|
|
624
|
-
project_id: this.config.projectId,
|
|
625
683
|
callback_url: data.callbackUrl
|
|
626
684
|
})
|
|
627
685
|
});
|
|
@@ -644,10 +702,12 @@ var AuthGateClient = class {
|
|
|
644
702
|
`${this.config.baseUrl}/api/proxy/token/refresh`,
|
|
645
703
|
{
|
|
646
704
|
method: "POST",
|
|
647
|
-
headers: {
|
|
705
|
+
headers: {
|
|
706
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
707
|
+
"Content-Type": "application/json"
|
|
708
|
+
},
|
|
648
709
|
body: JSON.stringify({
|
|
649
|
-
refresh_token: refreshToken
|
|
650
|
-
project_id: this.config.projectId
|
|
710
|
+
refresh_token: refreshToken
|
|
651
711
|
})
|
|
652
712
|
}
|
|
653
713
|
);
|
|
@@ -672,10 +732,12 @@ var AuthGateClient = class {
|
|
|
672
732
|
`${this.config.baseUrl}/api/proxy/sessions/revoke`,
|
|
673
733
|
{
|
|
674
734
|
method: "POST",
|
|
675
|
-
headers: {
|
|
735
|
+
headers: {
|
|
736
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
737
|
+
"Content-Type": "application/json"
|
|
738
|
+
},
|
|
676
739
|
body: JSON.stringify({
|
|
677
|
-
refresh_token: refreshToken
|
|
678
|
-
project_id: this.config.projectId
|
|
740
|
+
refresh_token: refreshToken
|
|
679
741
|
})
|
|
680
742
|
}
|
|
681
743
|
);
|
|
@@ -698,10 +760,11 @@ var AuthGateClient = class {
|
|
|
698
760
|
async mfaVerify(data) {
|
|
699
761
|
return fetch(`${this.config.baseUrl}/api/proxy/mfa/verify`, {
|
|
700
762
|
method: "POST",
|
|
701
|
-
headers: {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
}
|
|
763
|
+
headers: {
|
|
764
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
765
|
+
"Content-Type": "application/json"
|
|
766
|
+
},
|
|
767
|
+
body: JSON.stringify(data)
|
|
705
768
|
});
|
|
706
769
|
}
|
|
707
770
|
/**
|
|
@@ -832,11 +895,11 @@ var AuthGateClient = class {
|
|
|
832
895
|
async mfaSmsSendCode(challenge) {
|
|
833
896
|
return fetch(`${this.config.baseUrl}/api/proxy/mfa/sms/send-code`, {
|
|
834
897
|
method: "POST",
|
|
835
|
-
headers: {
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
})
|
|
898
|
+
headers: {
|
|
899
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
900
|
+
"Content-Type": "application/json"
|
|
901
|
+
},
|
|
902
|
+
body: JSON.stringify({ challenge })
|
|
840
903
|
});
|
|
841
904
|
}
|
|
842
905
|
// ---------------------------------------------------------------------------
|
|
@@ -858,10 +921,6 @@ var AuthGateClient = class {
|
|
|
858
921
|
get callbackPath() {
|
|
859
922
|
return this.config.callbackPath;
|
|
860
923
|
}
|
|
861
|
-
/** The AuthGate project ID. */
|
|
862
|
-
get projectId() {
|
|
863
|
-
return this.config.projectId;
|
|
864
|
-
}
|
|
865
924
|
/** The AuthGate service base URL. */
|
|
866
925
|
get baseUrl() {
|
|
867
926
|
return this.config.baseUrl;
|
|
@@ -899,7 +958,71 @@ var AuthGateClient = class {
|
|
|
899
958
|
path: "/"
|
|
900
959
|
};
|
|
901
960
|
}
|
|
961
|
+
// ---------------------------------------------------------------------------
|
|
962
|
+
// Config validation (async, called by framework factories)
|
|
963
|
+
// ---------------------------------------------------------------------------
|
|
964
|
+
/**
|
|
965
|
+
* Validate the SDK configuration against the AuthGate server.
|
|
966
|
+
*
|
|
967
|
+
* Checks that the API key is valid and (optionally) that a callback URL
|
|
968
|
+
* is registered for the project. This is called automatically by framework
|
|
969
|
+
* factories (`createAuthGate`, `createAuthRoutes`) and logs errors to the
|
|
970
|
+
* console — it does NOT throw.
|
|
971
|
+
*
|
|
972
|
+
* @param callbackUrl - The full callback URL to check registration for.
|
|
973
|
+
* @internal
|
|
974
|
+
*/
|
|
975
|
+
async validateConfig(callbackUrl) {
|
|
976
|
+
try {
|
|
977
|
+
const response = await fetch(
|
|
978
|
+
`${this.config.baseUrl}/api/v1/config/validate`,
|
|
979
|
+
{
|
|
980
|
+
method: "POST",
|
|
981
|
+
headers: {
|
|
982
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
983
|
+
"Content-Type": "application/json"
|
|
984
|
+
},
|
|
985
|
+
body: JSON.stringify({
|
|
986
|
+
callback_url: callbackUrl
|
|
987
|
+
})
|
|
988
|
+
}
|
|
989
|
+
);
|
|
990
|
+
if (response.status === 401) {
|
|
991
|
+
console.error(
|
|
992
|
+
"\n[AuthGate] \u2717 Invalid API key.\n The API key you provided is not recognized or has been revoked.\n \u2192 Go to your AuthGate dashboard \u2192 Project \u2192 API Key to get a valid key.\n"
|
|
993
|
+
);
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
if (!response.ok) {
|
|
997
|
+
console.warn(
|
|
998
|
+
"[AuthGate] Could not validate config (server returned " + response.status + "). Auth flows may fail."
|
|
999
|
+
);
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
const data = await response.json();
|
|
1003
|
+
if (callbackUrl && data.callback_url_registered === false) {
|
|
1004
|
+
console.error(
|
|
1005
|
+
"\n[AuthGate] \u2717 Callback URL not registered: " + callbackUrl + "\n This URL must be added to your project's allowed callback URLs.\n \u2192 Go to your AuthGate dashboard \u2192 Project \u2192 Callback URLs \u2192 Add URL.\n"
|
|
1006
|
+
);
|
|
1007
|
+
}
|
|
1008
|
+
} catch (e) {
|
|
1009
|
+
console.warn(
|
|
1010
|
+
"[AuthGate] Could not reach AuthGate server at " + this.config.baseUrl + " to validate config. Auth flows may fail if the URL is wrong."
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
902
1014
|
};
|
|
903
1015
|
function createAuthGateClient(config) {
|
|
904
1016
|
return new AuthGateClient(config);
|
|
905
1017
|
}
|
|
1018
|
+
|
|
1019
|
+
// src/billing.ts
|
|
1020
|
+
function hasPlan(entitlements, plan) {
|
|
1021
|
+
if (!(entitlements == null ? void 0 : entitlements.plan)) return false;
|
|
1022
|
+
return entitlements.plan.toLowerCase() === plan.toLowerCase();
|
|
1023
|
+
}
|
|
1024
|
+
function hasFeature(entitlements, feature) {
|
|
1025
|
+
if (!(entitlements == null ? void 0 : entitlements.features)) return false;
|
|
1026
|
+
const lower = feature.toLowerCase();
|
|
1027
|
+
return entitlements.features.some((f) => f.toLowerCase() === lower);
|
|
1028
|
+
}
|
package/dist/index.d.cts
CHANGED
|
@@ -47,16 +47,13 @@ interface TokenVerifyResult {
|
|
|
47
47
|
*
|
|
48
48
|
* const client = createAuthGateClient({
|
|
49
49
|
* apiKey: process.env.AUTHGATE_API_KEY!,
|
|
50
|
-
* projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
51
50
|
* baseUrl: "https://authgate.dev",
|
|
52
51
|
* });
|
|
53
52
|
* ```
|
|
54
53
|
*/
|
|
55
54
|
interface AuthGateConfig {
|
|
56
|
-
/** Server-side API key for your AuthGate project. Found in the dashboard under API
|
|
55
|
+
/** Server-side API key for your AuthGate project. Found in the dashboard under API Key. */
|
|
57
56
|
apiKey: string;
|
|
58
|
-
/** The project ID from your AuthGate dashboard. */
|
|
59
|
-
projectId: string;
|
|
60
57
|
/** Base URL of the AuthGate service (e.g. `"https://authgate.dev"`). */
|
|
61
58
|
baseUrl: string;
|
|
62
59
|
/**
|
|
@@ -172,7 +169,6 @@ interface BackupCodesResponse {
|
|
|
172
169
|
* ```ts
|
|
173
170
|
* const client = new AuthGateClient({
|
|
174
171
|
* apiKey: process.env.AUTHGATE_API_KEY!,
|
|
175
|
-
* projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
176
172
|
* baseUrl: "https://authgate.dev",
|
|
177
173
|
* });
|
|
178
174
|
* ```
|
|
@@ -262,8 +258,9 @@ declare class AuthGateClient {
|
|
|
262
258
|
* @throws {@link AuthGateError} if the provider is not in {@link SUPPORTED_PROVIDERS}.
|
|
263
259
|
*/
|
|
264
260
|
getOAuthUrl(provider: OAuthProvider, callbackUrl: string, options?: {
|
|
261
|
+
state?: string;
|
|
265
262
|
linkTo?: string;
|
|
266
|
-
}): string
|
|
263
|
+
}): Promise<string>;
|
|
267
264
|
/**
|
|
268
265
|
* Register a new user with email and password.
|
|
269
266
|
*
|
|
@@ -459,8 +456,6 @@ declare class AuthGateClient {
|
|
|
459
456
|
get refreshTokenCookieName(): string;
|
|
460
457
|
/** The callback path where OAuth redirects are handled (default: `"/api/auth/callback"`). */
|
|
461
458
|
get callbackPath(): string;
|
|
462
|
-
/** The AuthGate project ID. */
|
|
463
|
-
get projectId(): string;
|
|
464
459
|
/** The AuthGate service base URL. */
|
|
465
460
|
get baseUrl(): string;
|
|
466
461
|
/** Session lifetime in seconds. */
|
|
@@ -477,6 +472,18 @@ declare class AuthGateClient {
|
|
|
477
472
|
* Short-lived (10 minutes) to match the state TTL.
|
|
478
473
|
*/
|
|
479
474
|
getNonceCookieOptions(): CookieOptions;
|
|
475
|
+
/**
|
|
476
|
+
* Validate the SDK configuration against the AuthGate server.
|
|
477
|
+
*
|
|
478
|
+
* Checks that the API key is valid and (optionally) that a callback URL
|
|
479
|
+
* is registered for the project. This is called automatically by framework
|
|
480
|
+
* factories (`createAuthGate`, `createAuthRoutes`) and logs errors to the
|
|
481
|
+
* console — it does NOT throw.
|
|
482
|
+
*
|
|
483
|
+
* @param callbackUrl - The full callback URL to check registration for.
|
|
484
|
+
* @internal
|
|
485
|
+
*/
|
|
486
|
+
validateConfig(callbackUrl?: string): Promise<void>;
|
|
480
487
|
}
|
|
481
488
|
/**
|
|
482
489
|
* Create an {@link AuthGateClient} instance.
|
|
@@ -557,5 +564,79 @@ declare class SessionDecryptionError extends AuthGateError {
|
|
|
557
564
|
declare class InvalidStateError extends AuthGateError {
|
|
558
565
|
constructor(message?: string);
|
|
559
566
|
}
|
|
567
|
+
/**
|
|
568
|
+
* Thrown when the AuthGate SDK is initialized with invalid configuration.
|
|
569
|
+
*
|
|
570
|
+
* Check the error message for details on which config field is invalid
|
|
571
|
+
* and how to fix it.
|
|
572
|
+
*/
|
|
573
|
+
declare class ConfigurationError extends AuthGateError {
|
|
574
|
+
constructor(message: string);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/** A product/plan in the billing catalog. */
|
|
578
|
+
interface BillingPlan {
|
|
579
|
+
id: string;
|
|
580
|
+
name: string;
|
|
581
|
+
description: string | null;
|
|
582
|
+
features: string[];
|
|
583
|
+
prices: BillingPrice[];
|
|
584
|
+
}
|
|
585
|
+
/** A price attached to a plan. */
|
|
586
|
+
interface BillingPrice {
|
|
587
|
+
id: string;
|
|
588
|
+
type: "recurring" | "metered" | "tiered";
|
|
589
|
+
amount: number | null;
|
|
590
|
+
currency: string;
|
|
591
|
+
interval: "daily" | "weekly" | "monthly" | "yearly";
|
|
592
|
+
intervalCount: number;
|
|
593
|
+
}
|
|
594
|
+
/** An active subscription for an end user. */
|
|
595
|
+
interface BillingSubscription {
|
|
596
|
+
id: string;
|
|
597
|
+
status: "active" | "past_due" | "canceled" | "paused" | "trialing" | "unpaid";
|
|
598
|
+
plan: {
|
|
599
|
+
id: string;
|
|
600
|
+
name: string;
|
|
601
|
+
} | null;
|
|
602
|
+
price: BillingPrice | null;
|
|
603
|
+
currentPeriodStart: string;
|
|
604
|
+
currentPeriodEnd: string;
|
|
605
|
+
cancelAtPeriodEnd: boolean;
|
|
606
|
+
trialEnd: string | null;
|
|
607
|
+
}
|
|
608
|
+
/** Entitlement data for an end user — what plan they're on and what features they have. */
|
|
609
|
+
interface BillingEntitlement {
|
|
610
|
+
plan: string | null;
|
|
611
|
+
features: string[];
|
|
612
|
+
status: string | null;
|
|
613
|
+
subscription: {
|
|
614
|
+
id: string;
|
|
615
|
+
currentPeriodEnd: string;
|
|
616
|
+
} | null;
|
|
617
|
+
}
|
|
618
|
+
/** A single usage event to report. */
|
|
619
|
+
interface UsageEvent {
|
|
620
|
+
metric: string;
|
|
621
|
+
quantity: number;
|
|
622
|
+
idempotencyKey?: string;
|
|
623
|
+
timestamp?: string;
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Check whether the user's entitlements include a specific plan.
|
|
627
|
+
*
|
|
628
|
+
* @param entitlements - The entitlement object from the billing API.
|
|
629
|
+
* @param plan - The plan name to check (case-insensitive).
|
|
630
|
+
* @returns `true` if the user is on the given plan.
|
|
631
|
+
*/
|
|
632
|
+
declare function hasPlan(entitlements: BillingEntitlement | null | undefined, plan: string): boolean;
|
|
633
|
+
/**
|
|
634
|
+
* Check whether the user's entitlements include a specific feature.
|
|
635
|
+
*
|
|
636
|
+
* @param entitlements - The entitlement object from the billing API.
|
|
637
|
+
* @param feature - The feature name to check (case-insensitive).
|
|
638
|
+
* @returns `true` if the user has the given feature.
|
|
639
|
+
*/
|
|
640
|
+
declare function hasFeature(entitlements: BillingEntitlement | null | undefined, feature: string): boolean;
|
|
560
641
|
|
|
561
|
-
export { AuthGateClient, type AuthGateConfig, AuthGateError, type AuthGateUser, type BackupCodesResponse, type CookieOptions, DEFAULT_COOKIE_NAME, InvalidStateError, type MfaChallengeResponse, type MfaStatus, NONCE_COOKIE_NAME, type OAuthProvider, REFRESH_TOKEN_COOKIE_NAME, SESSION_MAX_AGE, STATE_TTL_MS, SUPPORTED_PROVIDERS, SessionDecryptionError, type SessionPayload, TokenVerificationError, type TokenVerifyResult, type TotpSetupResponse, createAuthGateClient };
|
|
642
|
+
export { AuthGateClient, type AuthGateConfig, AuthGateError, type AuthGateUser, type BackupCodesResponse, type BillingEntitlement, type BillingPlan, type BillingPrice, type BillingSubscription, ConfigurationError, type CookieOptions, DEFAULT_COOKIE_NAME, InvalidStateError, type MfaChallengeResponse, type MfaStatus, NONCE_COOKIE_NAME, type OAuthProvider, REFRESH_TOKEN_COOKIE_NAME, SESSION_MAX_AGE, STATE_TTL_MS, SUPPORTED_PROVIDERS, SessionDecryptionError, type SessionPayload, TokenVerificationError, type TokenVerifyResult, type TotpSetupResponse, type UsageEvent, createAuthGateClient, hasFeature, hasPlan };
|
package/dist/index.d.ts
CHANGED
|
@@ -47,16 +47,13 @@ interface TokenVerifyResult {
|
|
|
47
47
|
*
|
|
48
48
|
* const client = createAuthGateClient({
|
|
49
49
|
* apiKey: process.env.AUTHGATE_API_KEY!,
|
|
50
|
-
* projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
51
50
|
* baseUrl: "https://authgate.dev",
|
|
52
51
|
* });
|
|
53
52
|
* ```
|
|
54
53
|
*/
|
|
55
54
|
interface AuthGateConfig {
|
|
56
|
-
/** Server-side API key for your AuthGate project. Found in the dashboard under API
|
|
55
|
+
/** Server-side API key for your AuthGate project. Found in the dashboard under API Key. */
|
|
57
56
|
apiKey: string;
|
|
58
|
-
/** The project ID from your AuthGate dashboard. */
|
|
59
|
-
projectId: string;
|
|
60
57
|
/** Base URL of the AuthGate service (e.g. `"https://authgate.dev"`). */
|
|
61
58
|
baseUrl: string;
|
|
62
59
|
/**
|
|
@@ -172,7 +169,6 @@ interface BackupCodesResponse {
|
|
|
172
169
|
* ```ts
|
|
173
170
|
* const client = new AuthGateClient({
|
|
174
171
|
* apiKey: process.env.AUTHGATE_API_KEY!,
|
|
175
|
-
* projectId: process.env.AUTHGATE_PROJECT_ID!,
|
|
176
172
|
* baseUrl: "https://authgate.dev",
|
|
177
173
|
* });
|
|
178
174
|
* ```
|
|
@@ -262,8 +258,9 @@ declare class AuthGateClient {
|
|
|
262
258
|
* @throws {@link AuthGateError} if the provider is not in {@link SUPPORTED_PROVIDERS}.
|
|
263
259
|
*/
|
|
264
260
|
getOAuthUrl(provider: OAuthProvider, callbackUrl: string, options?: {
|
|
261
|
+
state?: string;
|
|
265
262
|
linkTo?: string;
|
|
266
|
-
}): string
|
|
263
|
+
}): Promise<string>;
|
|
267
264
|
/**
|
|
268
265
|
* Register a new user with email and password.
|
|
269
266
|
*
|
|
@@ -459,8 +456,6 @@ declare class AuthGateClient {
|
|
|
459
456
|
get refreshTokenCookieName(): string;
|
|
460
457
|
/** The callback path where OAuth redirects are handled (default: `"/api/auth/callback"`). */
|
|
461
458
|
get callbackPath(): string;
|
|
462
|
-
/** The AuthGate project ID. */
|
|
463
|
-
get projectId(): string;
|
|
464
459
|
/** The AuthGate service base URL. */
|
|
465
460
|
get baseUrl(): string;
|
|
466
461
|
/** Session lifetime in seconds. */
|
|
@@ -477,6 +472,18 @@ declare class AuthGateClient {
|
|
|
477
472
|
* Short-lived (10 minutes) to match the state TTL.
|
|
478
473
|
*/
|
|
479
474
|
getNonceCookieOptions(): CookieOptions;
|
|
475
|
+
/**
|
|
476
|
+
* Validate the SDK configuration against the AuthGate server.
|
|
477
|
+
*
|
|
478
|
+
* Checks that the API key is valid and (optionally) that a callback URL
|
|
479
|
+
* is registered for the project. This is called automatically by framework
|
|
480
|
+
* factories (`createAuthGate`, `createAuthRoutes`) and logs errors to the
|
|
481
|
+
* console — it does NOT throw.
|
|
482
|
+
*
|
|
483
|
+
* @param callbackUrl - The full callback URL to check registration for.
|
|
484
|
+
* @internal
|
|
485
|
+
*/
|
|
486
|
+
validateConfig(callbackUrl?: string): Promise<void>;
|
|
480
487
|
}
|
|
481
488
|
/**
|
|
482
489
|
* Create an {@link AuthGateClient} instance.
|
|
@@ -557,5 +564,79 @@ declare class SessionDecryptionError extends AuthGateError {
|
|
|
557
564
|
declare class InvalidStateError extends AuthGateError {
|
|
558
565
|
constructor(message?: string);
|
|
559
566
|
}
|
|
567
|
+
/**
|
|
568
|
+
* Thrown when the AuthGate SDK is initialized with invalid configuration.
|
|
569
|
+
*
|
|
570
|
+
* Check the error message for details on which config field is invalid
|
|
571
|
+
* and how to fix it.
|
|
572
|
+
*/
|
|
573
|
+
declare class ConfigurationError extends AuthGateError {
|
|
574
|
+
constructor(message: string);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/** A product/plan in the billing catalog. */
|
|
578
|
+
interface BillingPlan {
|
|
579
|
+
id: string;
|
|
580
|
+
name: string;
|
|
581
|
+
description: string | null;
|
|
582
|
+
features: string[];
|
|
583
|
+
prices: BillingPrice[];
|
|
584
|
+
}
|
|
585
|
+
/** A price attached to a plan. */
|
|
586
|
+
interface BillingPrice {
|
|
587
|
+
id: string;
|
|
588
|
+
type: "recurring" | "metered" | "tiered";
|
|
589
|
+
amount: number | null;
|
|
590
|
+
currency: string;
|
|
591
|
+
interval: "daily" | "weekly" | "monthly" | "yearly";
|
|
592
|
+
intervalCount: number;
|
|
593
|
+
}
|
|
594
|
+
/** An active subscription for an end user. */
|
|
595
|
+
interface BillingSubscription {
|
|
596
|
+
id: string;
|
|
597
|
+
status: "active" | "past_due" | "canceled" | "paused" | "trialing" | "unpaid";
|
|
598
|
+
plan: {
|
|
599
|
+
id: string;
|
|
600
|
+
name: string;
|
|
601
|
+
} | null;
|
|
602
|
+
price: BillingPrice | null;
|
|
603
|
+
currentPeriodStart: string;
|
|
604
|
+
currentPeriodEnd: string;
|
|
605
|
+
cancelAtPeriodEnd: boolean;
|
|
606
|
+
trialEnd: string | null;
|
|
607
|
+
}
|
|
608
|
+
/** Entitlement data for an end user — what plan they're on and what features they have. */
|
|
609
|
+
interface BillingEntitlement {
|
|
610
|
+
plan: string | null;
|
|
611
|
+
features: string[];
|
|
612
|
+
status: string | null;
|
|
613
|
+
subscription: {
|
|
614
|
+
id: string;
|
|
615
|
+
currentPeriodEnd: string;
|
|
616
|
+
} | null;
|
|
617
|
+
}
|
|
618
|
+
/** A single usage event to report. */
|
|
619
|
+
interface UsageEvent {
|
|
620
|
+
metric: string;
|
|
621
|
+
quantity: number;
|
|
622
|
+
idempotencyKey?: string;
|
|
623
|
+
timestamp?: string;
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Check whether the user's entitlements include a specific plan.
|
|
627
|
+
*
|
|
628
|
+
* @param entitlements - The entitlement object from the billing API.
|
|
629
|
+
* @param plan - The plan name to check (case-insensitive).
|
|
630
|
+
* @returns `true` if the user is on the given plan.
|
|
631
|
+
*/
|
|
632
|
+
declare function hasPlan(entitlements: BillingEntitlement | null | undefined, plan: string): boolean;
|
|
633
|
+
/**
|
|
634
|
+
* Check whether the user's entitlements include a specific feature.
|
|
635
|
+
*
|
|
636
|
+
* @param entitlements - The entitlement object from the billing API.
|
|
637
|
+
* @param feature - The feature name to check (case-insensitive).
|
|
638
|
+
* @returns `true` if the user has the given feature.
|
|
639
|
+
*/
|
|
640
|
+
declare function hasFeature(entitlements: BillingEntitlement | null | undefined, feature: string): boolean;
|
|
560
641
|
|
|
561
|
-
export { AuthGateClient, type AuthGateConfig, AuthGateError, type AuthGateUser, type BackupCodesResponse, type CookieOptions, DEFAULT_COOKIE_NAME, InvalidStateError, type MfaChallengeResponse, type MfaStatus, NONCE_COOKIE_NAME, type OAuthProvider, REFRESH_TOKEN_COOKIE_NAME, SESSION_MAX_AGE, STATE_TTL_MS, SUPPORTED_PROVIDERS, SessionDecryptionError, type SessionPayload, TokenVerificationError, type TokenVerifyResult, type TotpSetupResponse, createAuthGateClient };
|
|
642
|
+
export { AuthGateClient, type AuthGateConfig, AuthGateError, type AuthGateUser, type BackupCodesResponse, type BillingEntitlement, type BillingPlan, type BillingPrice, type BillingSubscription, ConfigurationError, type CookieOptions, DEFAULT_COOKIE_NAME, InvalidStateError, type MfaChallengeResponse, type MfaStatus, NONCE_COOKIE_NAME, type OAuthProvider, REFRESH_TOKEN_COOKIE_NAME, SESSION_MAX_AGE, STATE_TTL_MS, SUPPORTED_PROVIDERS, SessionDecryptionError, type SessionPayload, TokenVerificationError, type TokenVerifyResult, type TotpSetupResponse, type UsageEvent, createAuthGateClient, hasFeature, hasPlan };
|
package/dist/index.mjs
CHANGED
|
@@ -262,6 +262,12 @@ var InvalidStateError = class extends AuthGateError {
|
|
|
262
262
|
this.name = "InvalidStateError";
|
|
263
263
|
}
|
|
264
264
|
};
|
|
265
|
+
var ConfigurationError = class extends AuthGateError {
|
|
266
|
+
constructor(message) {
|
|
267
|
+
super(message);
|
|
268
|
+
this.name = "ConfigurationError";
|
|
269
|
+
}
|
|
270
|
+
};
|
|
265
271
|
|
|
266
272
|
// src/client.ts
|
|
267
273
|
var AuthGateClient = class {
|
|
@@ -272,6 +278,28 @@ var AuthGateClient = class {
|
|
|
272
278
|
this.encryptionKey = null;
|
|
273
279
|
this.stateKey = null;
|
|
274
280
|
var _a, _b, _c;
|
|
281
|
+
if (!config.apiKey || typeof config.apiKey !== "string" || config.apiKey.trim() === "") {
|
|
282
|
+
throw new ConfigurationError(
|
|
283
|
+
"[AuthGate] Missing or empty `apiKey`. Get your API key from the AuthGate dashboard \u2192 Project \u2192 API Key."
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
if (!config.baseUrl || typeof config.baseUrl !== "string" || config.baseUrl.trim() === "") {
|
|
287
|
+
throw new ConfigurationError(
|
|
288
|
+
'[AuthGate] Missing or empty `baseUrl`. Set this to your AuthGate service URL (e.g. "https://authgate.dev").'
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
new URL(config.baseUrl);
|
|
293
|
+
} catch (e) {
|
|
294
|
+
throw new ConfigurationError(
|
|
295
|
+
`[AuthGate] Invalid \`baseUrl\`: "${config.baseUrl}". Must be a valid URL (e.g. "https://authgate.dev").`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
if (config.callbackPath !== void 0 && !config.callbackPath.startsWith("/")) {
|
|
299
|
+
throw new ConfigurationError(
|
|
300
|
+
`[AuthGate] Invalid \`callbackPath\`: "${config.callbackPath}". Must start with "/" (e.g. "/api/auth/callback").`
|
|
301
|
+
);
|
|
302
|
+
}
|
|
275
303
|
this.config = __spreadProps(__spreadValues({}, config), {
|
|
276
304
|
cookieName: (_a = config.cookieName) != null ? _a : DEFAULT_COOKIE_NAME,
|
|
277
305
|
sessionMaxAge: (_b = config.sessionMaxAge) != null ? _b : SESSION_MAX_AGE,
|
|
@@ -419,17 +447,28 @@ var AuthGateClient = class {
|
|
|
419
447
|
* @returns The full authorization URL to redirect the user to.
|
|
420
448
|
* @throws {@link AuthGateError} if the provider is not in {@link SUPPORTED_PROVIDERS}.
|
|
421
449
|
*/
|
|
422
|
-
getOAuthUrl(provider, callbackUrl, options) {
|
|
450
|
+
async getOAuthUrl(provider, callbackUrl, options) {
|
|
423
451
|
if (!SUPPORTED_PROVIDERS.includes(provider)) {
|
|
424
452
|
throw new AuthGateError(`Unsupported provider: ${provider}`);
|
|
425
453
|
}
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
454
|
+
const response = await fetch(`${this.config.baseUrl}/api/proxy/${provider}`, {
|
|
455
|
+
method: "POST",
|
|
456
|
+
headers: {
|
|
457
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
458
|
+
"Content-Type": "application/json"
|
|
459
|
+
},
|
|
460
|
+
body: JSON.stringify({
|
|
461
|
+
callback_url: callbackUrl,
|
|
462
|
+
state: options == null ? void 0 : options.state,
|
|
463
|
+
link_to: options == null ? void 0 : options.linkTo
|
|
464
|
+
})
|
|
465
|
+
});
|
|
466
|
+
if (!response.ok) {
|
|
467
|
+
const error = await response.json().catch(() => ({}));
|
|
468
|
+
throw new AuthGateError(error.error || `OAuth initiation failed: ${response.status}`);
|
|
431
469
|
}
|
|
432
|
-
|
|
470
|
+
const data = await response.json();
|
|
471
|
+
return data.redirect_url;
|
|
433
472
|
}
|
|
434
473
|
// ---------------------------------------------------------------------------
|
|
435
474
|
// Email auth
|
|
@@ -443,12 +482,14 @@ var AuthGateClient = class {
|
|
|
443
482
|
async emailSignup(data) {
|
|
444
483
|
return fetch(`${this.config.baseUrl}/api/proxy/email/signup`, {
|
|
445
484
|
method: "POST",
|
|
446
|
-
headers: {
|
|
485
|
+
headers: {
|
|
486
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
487
|
+
"Content-Type": "application/json"
|
|
488
|
+
},
|
|
447
489
|
body: JSON.stringify({
|
|
448
490
|
email: data.email,
|
|
449
491
|
password: data.password,
|
|
450
492
|
name: data.name,
|
|
451
|
-
project_id: this.config.projectId,
|
|
452
493
|
callback_url: data.callbackUrl
|
|
453
494
|
})
|
|
454
495
|
});
|
|
@@ -465,11 +506,13 @@ var AuthGateClient = class {
|
|
|
465
506
|
async emailSignin(data) {
|
|
466
507
|
return fetch(`${this.config.baseUrl}/api/proxy/email/signin`, {
|
|
467
508
|
method: "POST",
|
|
468
|
-
headers: {
|
|
509
|
+
headers: {
|
|
510
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
511
|
+
"Content-Type": "application/json"
|
|
512
|
+
},
|
|
469
513
|
body: JSON.stringify({
|
|
470
514
|
email: data.email,
|
|
471
515
|
password: data.password,
|
|
472
|
-
project_id: this.config.projectId,
|
|
473
516
|
callback_url: data.callbackUrl
|
|
474
517
|
})
|
|
475
518
|
});
|
|
@@ -483,10 +526,12 @@ var AuthGateClient = class {
|
|
|
483
526
|
async emailForgotPassword(data) {
|
|
484
527
|
return fetch(`${this.config.baseUrl}/api/proxy/email/reset-password`, {
|
|
485
528
|
method: "POST",
|
|
486
|
-
headers: {
|
|
529
|
+
headers: {
|
|
530
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
531
|
+
"Content-Type": "application/json"
|
|
532
|
+
},
|
|
487
533
|
body: JSON.stringify({
|
|
488
534
|
email: data.email,
|
|
489
|
-
project_id: this.config.projectId,
|
|
490
535
|
callback_url: data.callbackUrl
|
|
491
536
|
})
|
|
492
537
|
});
|
|
@@ -502,11 +547,13 @@ var AuthGateClient = class {
|
|
|
502
547
|
`${this.config.baseUrl}/api/proxy/email/reset-password/confirm`,
|
|
503
548
|
{
|
|
504
549
|
method: "POST",
|
|
505
|
-
headers: {
|
|
550
|
+
headers: {
|
|
551
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
552
|
+
"Content-Type": "application/json"
|
|
553
|
+
},
|
|
506
554
|
body: JSON.stringify({
|
|
507
555
|
token: data.token,
|
|
508
|
-
password: data.password
|
|
509
|
-
project_id: this.config.projectId
|
|
556
|
+
password: data.password
|
|
510
557
|
})
|
|
511
558
|
}
|
|
512
559
|
);
|
|
@@ -525,10 +572,12 @@ var AuthGateClient = class {
|
|
|
525
572
|
`${this.config.baseUrl}/api/proxy/email/magic-link/send`,
|
|
526
573
|
{
|
|
527
574
|
method: "POST",
|
|
528
|
-
headers: {
|
|
575
|
+
headers: {
|
|
576
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
577
|
+
"Content-Type": "application/json"
|
|
578
|
+
},
|
|
529
579
|
body: JSON.stringify({
|
|
530
580
|
email: data.email,
|
|
531
|
-
project_id: this.config.projectId,
|
|
532
581
|
callback_url: data.callbackUrl
|
|
533
582
|
})
|
|
534
583
|
}
|
|
@@ -546,11 +595,13 @@ var AuthGateClient = class {
|
|
|
546
595
|
async emailVerifyCode(data) {
|
|
547
596
|
return fetch(`${this.config.baseUrl}/api/proxy/email/verify`, {
|
|
548
597
|
method: "POST",
|
|
549
|
-
headers: {
|
|
598
|
+
headers: {
|
|
599
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
600
|
+
"Content-Type": "application/json"
|
|
601
|
+
},
|
|
550
602
|
body: JSON.stringify({
|
|
551
603
|
email: data.email,
|
|
552
|
-
code: data.code
|
|
553
|
-
project_id: this.config.projectId
|
|
604
|
+
code: data.code
|
|
554
605
|
})
|
|
555
606
|
});
|
|
556
607
|
}
|
|
@@ -566,10 +617,12 @@ var AuthGateClient = class {
|
|
|
566
617
|
async smsSendCode(data) {
|
|
567
618
|
return fetch(`${this.config.baseUrl}/api/proxy/sms/send-code`, {
|
|
568
619
|
method: "POST",
|
|
569
|
-
headers: {
|
|
620
|
+
headers: {
|
|
621
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
622
|
+
"Content-Type": "application/json"
|
|
623
|
+
},
|
|
570
624
|
body: JSON.stringify({
|
|
571
625
|
phone: data.phone,
|
|
572
|
-
project_id: this.config.projectId,
|
|
573
626
|
callback_url: data.callbackUrl
|
|
574
627
|
})
|
|
575
628
|
});
|
|
@@ -583,11 +636,13 @@ var AuthGateClient = class {
|
|
|
583
636
|
async smsVerifyCode(data) {
|
|
584
637
|
return fetch(`${this.config.baseUrl}/api/proxy/sms/verify-code`, {
|
|
585
638
|
method: "POST",
|
|
586
|
-
headers: {
|
|
639
|
+
headers: {
|
|
640
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
641
|
+
"Content-Type": "application/json"
|
|
642
|
+
},
|
|
587
643
|
body: JSON.stringify({
|
|
588
644
|
phone: data.phone,
|
|
589
645
|
code: data.code,
|
|
590
|
-
project_id: this.config.projectId,
|
|
591
646
|
callback_url: data.callbackUrl
|
|
592
647
|
})
|
|
593
648
|
});
|
|
@@ -610,10 +665,12 @@ var AuthGateClient = class {
|
|
|
610
665
|
`${this.config.baseUrl}/api/proxy/token/refresh`,
|
|
611
666
|
{
|
|
612
667
|
method: "POST",
|
|
613
|
-
headers: {
|
|
668
|
+
headers: {
|
|
669
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
670
|
+
"Content-Type": "application/json"
|
|
671
|
+
},
|
|
614
672
|
body: JSON.stringify({
|
|
615
|
-
refresh_token: refreshToken
|
|
616
|
-
project_id: this.config.projectId
|
|
673
|
+
refresh_token: refreshToken
|
|
617
674
|
})
|
|
618
675
|
}
|
|
619
676
|
);
|
|
@@ -638,10 +695,12 @@ var AuthGateClient = class {
|
|
|
638
695
|
`${this.config.baseUrl}/api/proxy/sessions/revoke`,
|
|
639
696
|
{
|
|
640
697
|
method: "POST",
|
|
641
|
-
headers: {
|
|
698
|
+
headers: {
|
|
699
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
700
|
+
"Content-Type": "application/json"
|
|
701
|
+
},
|
|
642
702
|
body: JSON.stringify({
|
|
643
|
-
refresh_token: refreshToken
|
|
644
|
-
project_id: this.config.projectId
|
|
703
|
+
refresh_token: refreshToken
|
|
645
704
|
})
|
|
646
705
|
}
|
|
647
706
|
);
|
|
@@ -664,10 +723,11 @@ var AuthGateClient = class {
|
|
|
664
723
|
async mfaVerify(data) {
|
|
665
724
|
return fetch(`${this.config.baseUrl}/api/proxy/mfa/verify`, {
|
|
666
725
|
method: "POST",
|
|
667
|
-
headers: {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
}
|
|
726
|
+
headers: {
|
|
727
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
728
|
+
"Content-Type": "application/json"
|
|
729
|
+
},
|
|
730
|
+
body: JSON.stringify(data)
|
|
671
731
|
});
|
|
672
732
|
}
|
|
673
733
|
/**
|
|
@@ -798,11 +858,11 @@ var AuthGateClient = class {
|
|
|
798
858
|
async mfaSmsSendCode(challenge) {
|
|
799
859
|
return fetch(`${this.config.baseUrl}/api/proxy/mfa/sms/send-code`, {
|
|
800
860
|
method: "POST",
|
|
801
|
-
headers: {
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
})
|
|
861
|
+
headers: {
|
|
862
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
863
|
+
"Content-Type": "application/json"
|
|
864
|
+
},
|
|
865
|
+
body: JSON.stringify({ challenge })
|
|
806
866
|
});
|
|
807
867
|
}
|
|
808
868
|
// ---------------------------------------------------------------------------
|
|
@@ -824,10 +884,6 @@ var AuthGateClient = class {
|
|
|
824
884
|
get callbackPath() {
|
|
825
885
|
return this.config.callbackPath;
|
|
826
886
|
}
|
|
827
|
-
/** The AuthGate project ID. */
|
|
828
|
-
get projectId() {
|
|
829
|
-
return this.config.projectId;
|
|
830
|
-
}
|
|
831
887
|
/** The AuthGate service base URL. */
|
|
832
888
|
get baseUrl() {
|
|
833
889
|
return this.config.baseUrl;
|
|
@@ -865,13 +921,78 @@ var AuthGateClient = class {
|
|
|
865
921
|
path: "/"
|
|
866
922
|
};
|
|
867
923
|
}
|
|
924
|
+
// ---------------------------------------------------------------------------
|
|
925
|
+
// Config validation (async, called by framework factories)
|
|
926
|
+
// ---------------------------------------------------------------------------
|
|
927
|
+
/**
|
|
928
|
+
* Validate the SDK configuration against the AuthGate server.
|
|
929
|
+
*
|
|
930
|
+
* Checks that the API key is valid and (optionally) that a callback URL
|
|
931
|
+
* is registered for the project. This is called automatically by framework
|
|
932
|
+
* factories (`createAuthGate`, `createAuthRoutes`) and logs errors to the
|
|
933
|
+
* console — it does NOT throw.
|
|
934
|
+
*
|
|
935
|
+
* @param callbackUrl - The full callback URL to check registration for.
|
|
936
|
+
* @internal
|
|
937
|
+
*/
|
|
938
|
+
async validateConfig(callbackUrl) {
|
|
939
|
+
try {
|
|
940
|
+
const response = await fetch(
|
|
941
|
+
`${this.config.baseUrl}/api/v1/config/validate`,
|
|
942
|
+
{
|
|
943
|
+
method: "POST",
|
|
944
|
+
headers: {
|
|
945
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
946
|
+
"Content-Type": "application/json"
|
|
947
|
+
},
|
|
948
|
+
body: JSON.stringify({
|
|
949
|
+
callback_url: callbackUrl
|
|
950
|
+
})
|
|
951
|
+
}
|
|
952
|
+
);
|
|
953
|
+
if (response.status === 401) {
|
|
954
|
+
console.error(
|
|
955
|
+
"\n[AuthGate] \u2717 Invalid API key.\n The API key you provided is not recognized or has been revoked.\n \u2192 Go to your AuthGate dashboard \u2192 Project \u2192 API Key to get a valid key.\n"
|
|
956
|
+
);
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
if (!response.ok) {
|
|
960
|
+
console.warn(
|
|
961
|
+
"[AuthGate] Could not validate config (server returned " + response.status + "). Auth flows may fail."
|
|
962
|
+
);
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
const data = await response.json();
|
|
966
|
+
if (callbackUrl && data.callback_url_registered === false) {
|
|
967
|
+
console.error(
|
|
968
|
+
"\n[AuthGate] \u2717 Callback URL not registered: " + callbackUrl + "\n This URL must be added to your project's allowed callback URLs.\n \u2192 Go to your AuthGate dashboard \u2192 Project \u2192 Callback URLs \u2192 Add URL.\n"
|
|
969
|
+
);
|
|
970
|
+
}
|
|
971
|
+
} catch (e) {
|
|
972
|
+
console.warn(
|
|
973
|
+
"[AuthGate] Could not reach AuthGate server at " + this.config.baseUrl + " to validate config. Auth flows may fail if the URL is wrong."
|
|
974
|
+
);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
868
977
|
};
|
|
869
978
|
function createAuthGateClient(config) {
|
|
870
979
|
return new AuthGateClient(config);
|
|
871
980
|
}
|
|
981
|
+
|
|
982
|
+
// src/billing.ts
|
|
983
|
+
function hasPlan(entitlements, plan) {
|
|
984
|
+
if (!(entitlements == null ? void 0 : entitlements.plan)) return false;
|
|
985
|
+
return entitlements.plan.toLowerCase() === plan.toLowerCase();
|
|
986
|
+
}
|
|
987
|
+
function hasFeature(entitlements, feature) {
|
|
988
|
+
if (!(entitlements == null ? void 0 : entitlements.features)) return false;
|
|
989
|
+
const lower = feature.toLowerCase();
|
|
990
|
+
return entitlements.features.some((f) => f.toLowerCase() === lower);
|
|
991
|
+
}
|
|
872
992
|
export {
|
|
873
993
|
AuthGateClient,
|
|
874
994
|
AuthGateError,
|
|
995
|
+
ConfigurationError,
|
|
875
996
|
DEFAULT_COOKIE_NAME,
|
|
876
997
|
InvalidStateError,
|
|
877
998
|
NONCE_COOKIE_NAME,
|
|
@@ -881,5 +1002,7 @@ export {
|
|
|
881
1002
|
SUPPORTED_PROVIDERS,
|
|
882
1003
|
SessionDecryptionError,
|
|
883
1004
|
TokenVerificationError,
|
|
884
|
-
createAuthGateClient
|
|
1005
|
+
createAuthGateClient,
|
|
1006
|
+
hasFeature,
|
|
1007
|
+
hasPlan
|
|
885
1008
|
};
|