@meistrari/auth-core 1.15.0 → 1.17.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 +1 -398
- package/dist/index.d.mts +468 -24
- package/dist/index.d.ts +468 -24
- package/dist/index.mjs +147 -22
- package/package.json +5 -2
package/dist/index.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { defaultStatements } from 'better-auth/plugins/organization/access';
|
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
export { APIError } from 'better-auth';
|
|
10
10
|
|
|
11
|
-
const version = "1.
|
|
11
|
+
const version = "1.17.0";
|
|
12
12
|
|
|
13
13
|
const statements = {
|
|
14
14
|
...defaultStatements,
|
|
@@ -61,6 +61,13 @@ const memberAdditionalFields = {
|
|
|
61
61
|
defaultValue: null
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
|
+
const invitationAdditionalFields = {
|
|
65
|
+
applicationId: {
|
|
66
|
+
type: "string",
|
|
67
|
+
input: true,
|
|
68
|
+
required: false
|
|
69
|
+
}
|
|
70
|
+
};
|
|
64
71
|
const JWTPayloadUser = z.object({
|
|
65
72
|
id: z.string(),
|
|
66
73
|
name: z.string(),
|
|
@@ -100,6 +107,12 @@ function applicationsPluginClient() {
|
|
|
100
107
|
}
|
|
101
108
|
};
|
|
102
109
|
},
|
|
110
|
+
inviteUserToApplication: async (options) => {
|
|
111
|
+
return await $fetch("/applications/invitations", {
|
|
112
|
+
method: "POST",
|
|
113
|
+
body: options
|
|
114
|
+
});
|
|
115
|
+
},
|
|
103
116
|
startAuthorizationFlow: async (applicationId, redirectUri, codeChallenge, organizationId) => {
|
|
104
117
|
return await $fetch("/applications/authorize", {
|
|
105
118
|
method: "POST",
|
|
@@ -171,12 +184,17 @@ function applicationsPluginClient() {
|
|
|
171
184
|
headers
|
|
172
185
|
});
|
|
173
186
|
},
|
|
174
|
-
whoAmI: async (accessToken) => {
|
|
187
|
+
whoAmI: async (accessToken, options = {}) => {
|
|
175
188
|
const headers = new Headers();
|
|
176
189
|
headers.set("x-tela-access-token", accessToken);
|
|
190
|
+
const query = {};
|
|
191
|
+
if (options.include && options.include.length > 0) {
|
|
192
|
+
query.include = options.include.join(",");
|
|
193
|
+
}
|
|
177
194
|
return await $fetch("/applications/whoami", {
|
|
178
195
|
method: "GET",
|
|
179
|
-
headers
|
|
196
|
+
headers,
|
|
197
|
+
query
|
|
180
198
|
});
|
|
181
199
|
},
|
|
182
200
|
switchOrganization: async (organizationId, accessToken) => {
|
|
@@ -255,7 +273,13 @@ function createAPIClient(apiUrl, fetchOptions = {}) {
|
|
|
255
273
|
}
|
|
256
274
|
|
|
257
275
|
class BaseError extends Error {
|
|
276
|
+
/** Machine-readable error code (e.g. `"INVALID_SOCIAL_PROVIDER"`). */
|
|
258
277
|
code;
|
|
278
|
+
/**
|
|
279
|
+
* @param code - A machine-readable error code
|
|
280
|
+
* @param message - A human-readable error message
|
|
281
|
+
* @param options - Standard `ErrorOptions` (e.g. `cause`)
|
|
282
|
+
*/
|
|
259
283
|
constructor(code, message, options) {
|
|
260
284
|
super(message, options);
|
|
261
285
|
this.code = code;
|
|
@@ -374,6 +398,20 @@ class ApplicationService {
|
|
|
374
398
|
}
|
|
375
399
|
return response.data;
|
|
376
400
|
}
|
|
401
|
+
/**
|
|
402
|
+
* Invites a user to an application through an organization entitlement.
|
|
403
|
+
*
|
|
404
|
+
* @param options - Invitation details including organization, application, email, and role
|
|
405
|
+
* @returns The created invitation
|
|
406
|
+
*/
|
|
407
|
+
async inviteUserToApplication(options) {
|
|
408
|
+
const response = await this.client.applications.inviteUserToApplication(options);
|
|
409
|
+
const invitation = response.data;
|
|
410
|
+
if (!invitation) {
|
|
411
|
+
throw new Error("No invitation returned from application invitation endpoint");
|
|
412
|
+
}
|
|
413
|
+
return invitation;
|
|
414
|
+
}
|
|
377
415
|
/**
|
|
378
416
|
* Starts an authorization flow for a specific application.
|
|
379
417
|
*
|
|
@@ -389,6 +427,16 @@ class ApplicationService {
|
|
|
389
427
|
}
|
|
390
428
|
return response.data;
|
|
391
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* Starts a device authorization flow (RFC 8628).
|
|
432
|
+
*
|
|
433
|
+
* Returns a device code and user code that the end user must enter
|
|
434
|
+
* on the verification URI to authorize the device.
|
|
435
|
+
*
|
|
436
|
+
* @param requesterApplicationId - The application requesting authorization
|
|
437
|
+
* @param targetApplicationId - The target application to gain access to
|
|
438
|
+
* @returns Device authorization details including codes and verification URI
|
|
439
|
+
*/
|
|
392
440
|
async startDeviceAuthorizationFlow(requesterApplicationId, targetApplicationId) {
|
|
393
441
|
const response = await this.client.applications.startDeviceAuthorizationFlow(requesterApplicationId, targetApplicationId);
|
|
394
442
|
if (!response.data) {
|
|
@@ -396,6 +444,15 @@ class ApplicationService {
|
|
|
396
444
|
}
|
|
397
445
|
return response.data;
|
|
398
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* Retrieves the context for a pending device authorization request.
|
|
449
|
+
*
|
|
450
|
+
* Used by the authorization page to display details about the requesting
|
|
451
|
+
* and target applications before the user approves or denies.
|
|
452
|
+
*
|
|
453
|
+
* @param userCode - The user code from the device authorization response
|
|
454
|
+
* @returns Context including application info, available organizations, and status
|
|
455
|
+
*/
|
|
399
456
|
async getDeviceAuthorizationContext(userCode) {
|
|
400
457
|
const response = await this.client.applications.getDeviceAuthorizationContext(userCode);
|
|
401
458
|
if (!response.data) {
|
|
@@ -403,6 +460,13 @@ class ApplicationService {
|
|
|
403
460
|
}
|
|
404
461
|
return response.data;
|
|
405
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
* Approves a pending device authorization request.
|
|
465
|
+
*
|
|
466
|
+
* @param userCode - The user code identifying the device authorization request
|
|
467
|
+
* @param organizationId - The organization to authorize the device for
|
|
468
|
+
* @returns Confirmation of the approval action
|
|
469
|
+
*/
|
|
406
470
|
async approveDeviceAuthorizationFlow(userCode, organizationId) {
|
|
407
471
|
const response = await this.client.applications.approveDeviceAuthorizationFlow(userCode, organizationId);
|
|
408
472
|
if (!response.data) {
|
|
@@ -410,6 +474,12 @@ class ApplicationService {
|
|
|
410
474
|
}
|
|
411
475
|
return response.data;
|
|
412
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* Denies a pending device authorization request.
|
|
479
|
+
*
|
|
480
|
+
* @param userCode - The user code identifying the device authorization request
|
|
481
|
+
* @returns Confirmation of the denial action
|
|
482
|
+
*/
|
|
413
483
|
async denyDeviceAuthorizationFlow(userCode) {
|
|
414
484
|
const response = await this.client.applications.denyDeviceAuthorizationFlow(userCode);
|
|
415
485
|
if (!response.data) {
|
|
@@ -417,6 +487,21 @@ class ApplicationService {
|
|
|
417
487
|
}
|
|
418
488
|
return response.data;
|
|
419
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Exchanges a device code for access and refresh tokens.
|
|
492
|
+
*
|
|
493
|
+
* This should be called by the device client while polling. It will throw
|
|
494
|
+
* typed errors to indicate the polling state (pending, slow down, denied, expired).
|
|
495
|
+
*
|
|
496
|
+
* @param deviceCode - The device code obtained from {@link startDeviceAuthorizationFlow}
|
|
497
|
+
* @returns Access and refresh tokens along with user and organization info
|
|
498
|
+
*
|
|
499
|
+
* @throws {DeviceAuthorizationPendingError} The user hasn't authorized yet — keep polling
|
|
500
|
+
* @throws {DeviceAuthorizationSlowDownError} Polling too fast — increase the interval
|
|
501
|
+
* @throws {DeviceAccessDeniedError} The user denied the request
|
|
502
|
+
* @throws {DeviceCodeExpiredError} The device code has expired
|
|
503
|
+
* @throws {DeviceTransientServerError} Transient server error — safe to retry
|
|
504
|
+
*/
|
|
420
505
|
async exchangeDeviceCodeForTokens(deviceCode) {
|
|
421
506
|
try {
|
|
422
507
|
const response = await this.client.applications.exchangeDeviceCodeForTokens(deviceCode);
|
|
@@ -474,11 +559,16 @@ class ApplicationService {
|
|
|
474
559
|
/**
|
|
475
560
|
* Gets the current user and organization for a specific application.
|
|
476
561
|
*
|
|
562
|
+
* By default, the returned organization does not include its `members`,
|
|
563
|
+
* `teams`, or `invitations` collections. Pass `options.include` to request
|
|
564
|
+
* any of them explicitly.
|
|
565
|
+
*
|
|
477
566
|
* @param accessToken - The access token to use for the who am I request
|
|
567
|
+
* @param options - Optional include list controlling which relations are loaded
|
|
478
568
|
* @returns The current user and organization
|
|
479
569
|
*/
|
|
480
|
-
async whoAmI(accessToken) {
|
|
481
|
-
const response = await this.client.applications.whoAmI(accessToken);
|
|
570
|
+
async whoAmI(accessToken, options = {}) {
|
|
571
|
+
const response = await this.client.applications.whoAmI(accessToken, options);
|
|
482
572
|
if (!response.data) {
|
|
483
573
|
throw new Error("No data returned from the API", { cause: response.error });
|
|
484
574
|
}
|
|
@@ -560,10 +650,7 @@ class OrganizationService {
|
|
|
560
650
|
/**
|
|
561
651
|
* Updates an organization's details.
|
|
562
652
|
*
|
|
563
|
-
* @param payload - The organization fields to update
|
|
564
|
-
* @param payload.name - New organization name
|
|
565
|
-
* @param payload.logo - New organization logo URL
|
|
566
|
-
* @param payload.settings - New organization settings
|
|
653
|
+
* @param payload - The organization fields to update (name, logo, settings)
|
|
567
654
|
* @returns The updated organization
|
|
568
655
|
*/
|
|
569
656
|
async updateOrganization(payload) {
|
|
@@ -604,16 +691,19 @@ class OrganizationService {
|
|
|
604
691
|
* @param options.userEmail - Email address of the user to invite
|
|
605
692
|
* @param options.role - Role to assign to the invited user
|
|
606
693
|
* @param options.teamId - Team ID to add the user to
|
|
694
|
+
* @param options.applicationId - Legacy application scope; prefer applications.inviteUserToApplication for new app-scoped invites
|
|
607
695
|
* @param options.resend - Whether to resend if invitation already exists
|
|
608
696
|
* @returns The created invitation
|
|
609
697
|
*/
|
|
610
|
-
async inviteUserToOrganization({ userEmail, role, teamId, resend }) {
|
|
611
|
-
|
|
698
|
+
async inviteUserToOrganization({ userEmail, role, teamId, resend, applicationId }) {
|
|
699
|
+
const invitation = {
|
|
612
700
|
email: userEmail,
|
|
613
701
|
role,
|
|
614
702
|
teamId,
|
|
615
|
-
resend: resend ?? false
|
|
616
|
-
|
|
703
|
+
resend: resend ?? false,
|
|
704
|
+
applicationId
|
|
705
|
+
};
|
|
706
|
+
return await this.client.organization.inviteMember(invitation);
|
|
617
707
|
}
|
|
618
708
|
/**
|
|
619
709
|
* Cancels a pending organization invitation.
|
|
@@ -629,18 +719,19 @@ class OrganizationService {
|
|
|
629
719
|
* Accepts an organization invitation.
|
|
630
720
|
*
|
|
631
721
|
* @param id - The invitation ID to accept
|
|
722
|
+
* @returns Object containing the application's `homeUrl` when the invitation is
|
|
723
|
+
* scoped to an application that defines one; otherwise `null`.
|
|
632
724
|
*/
|
|
633
725
|
async acceptInvitation(id) {
|
|
634
|
-
await this.client.organization.acceptInvitation({
|
|
726
|
+
const response = await this.client.organization.acceptInvitation({
|
|
635
727
|
invitationId: id
|
|
636
728
|
});
|
|
729
|
+
return { homeUrl: response?.homeUrl ?? null };
|
|
637
730
|
}
|
|
638
731
|
/**
|
|
639
732
|
* Removes a user from the active organization.
|
|
640
733
|
*
|
|
641
|
-
* @param options -
|
|
642
|
-
* @param options.memberId - The member ID to remove
|
|
643
|
-
* @param options.userEmail - The user email to remove
|
|
734
|
+
* @param options - Provide either `memberId` or `userEmail` to identify the user
|
|
644
735
|
*/
|
|
645
736
|
async removeUserFromOrganization({ memberId, userEmail }) {
|
|
646
737
|
await this.client.organization.removeMember({
|
|
@@ -663,8 +754,7 @@ class OrganizationService {
|
|
|
663
754
|
/**
|
|
664
755
|
* Creates a new team within the active organization.
|
|
665
756
|
*
|
|
666
|
-
* @param payload - Team configuration
|
|
667
|
-
* @param payload.name - The name of the team
|
|
757
|
+
* @param payload - Team configuration with a `name` field
|
|
668
758
|
* @returns The created team
|
|
669
759
|
*/
|
|
670
760
|
async createTeam(payload) {
|
|
@@ -674,8 +764,7 @@ class OrganizationService {
|
|
|
674
764
|
* Updates an existing team's details.
|
|
675
765
|
*
|
|
676
766
|
* @param id - The team ID to update
|
|
677
|
-
* @param payload - Team fields to update
|
|
678
|
-
* @param payload.name - The new team name
|
|
767
|
+
* @param payload - Team fields to update (currently supports `name`)
|
|
679
768
|
* @returns The updated team
|
|
680
769
|
*/
|
|
681
770
|
async updateTeam(id, payload) {
|
|
@@ -934,6 +1023,15 @@ class ApiKeyService {
|
|
|
934
1023
|
constructor(client) {
|
|
935
1024
|
this.client = client;
|
|
936
1025
|
}
|
|
1026
|
+
/**
|
|
1027
|
+
* Creates a new API key.
|
|
1028
|
+
*
|
|
1029
|
+
* The returned object includes the secret `key` value, which is only
|
|
1030
|
+
* available at creation time and cannot be retrieved later.
|
|
1031
|
+
*
|
|
1032
|
+
* @param payload - The API key configuration
|
|
1033
|
+
* @returns The created API key including the secret key value
|
|
1034
|
+
*/
|
|
937
1035
|
async createApiKey(payload) {
|
|
938
1036
|
return await this.client.apiKey.create({
|
|
939
1037
|
name: payload.name,
|
|
@@ -942,6 +1040,12 @@ class ApiKeyService {
|
|
|
942
1040
|
metadata: payload.metadata
|
|
943
1041
|
});
|
|
944
1042
|
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Retrieves an API key by its ID.
|
|
1045
|
+
*
|
|
1046
|
+
* @param id - The API key ID
|
|
1047
|
+
* @returns The API key (without the secret key value)
|
|
1048
|
+
*/
|
|
945
1049
|
async getApiKey(id) {
|
|
946
1050
|
return await this.client.apiKey.get({
|
|
947
1051
|
query: {
|
|
@@ -949,18 +1053,39 @@ class ApiKeyService {
|
|
|
949
1053
|
}
|
|
950
1054
|
});
|
|
951
1055
|
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Lists all API keys owned by the authenticated user.
|
|
1058
|
+
*
|
|
1059
|
+
* @returns An object containing the API keys array and pagination metadata
|
|
1060
|
+
*/
|
|
952
1061
|
async listApiKeys() {
|
|
953
1062
|
return await this.client.apiKey.list();
|
|
954
1063
|
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Lists all API keys belonging to the active organization.
|
|
1066
|
+
*
|
|
1067
|
+
* @returns An array of API keys (without secret key values)
|
|
1068
|
+
*/
|
|
955
1069
|
async listOrganizationApiKeys() {
|
|
956
1070
|
return await this.client.customEndpoints.organizations.apiKeys();
|
|
957
1071
|
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Updates an existing API key.
|
|
1074
|
+
*
|
|
1075
|
+
* @param payload - The fields to update
|
|
1076
|
+
* @returns The updated API key (without the secret key value)
|
|
1077
|
+
*/
|
|
958
1078
|
async updateApiKey(payload) {
|
|
959
1079
|
return await this.client.apiKey.update({
|
|
960
1080
|
keyId: payload.id,
|
|
961
1081
|
name: payload.name
|
|
962
1082
|
});
|
|
963
1083
|
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Permanently deletes an API key.
|
|
1086
|
+
*
|
|
1087
|
+
* @param id - The API key ID to delete
|
|
1088
|
+
*/
|
|
964
1089
|
async deleteApiKey(id) {
|
|
965
1090
|
return await this.client.apiKey.delete({
|
|
966
1091
|
keyId: id
|
|
@@ -1034,4 +1159,4 @@ function extractTokenPayload(token) {
|
|
|
1034
1159
|
return payload;
|
|
1035
1160
|
}
|
|
1036
1161
|
|
|
1037
|
-
export { ApplicationError, AuthClient, AuthorizationFlowError, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadUser, JWTPayloadWorkspace, RefreshTokenExpiredError, Roles, UserNotLoggedInError, ac, extractTokenPayload, isTokenExpired, memberAdditionalFields, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
|
|
1162
|
+
export { ApplicationError, AuthClient, AuthorizationFlowError, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadUser, JWTPayloadWorkspace, RefreshTokenExpiredError, Roles, UserNotLoggedInError, ac, extractTokenPayload, invitationAdditionalFields, isTokenExpired, memberAdditionalFields, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meistrari/auth-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"dist"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "unbuild"
|
|
17
|
+
"build": "unbuild",
|
|
18
|
+
"docs": "typedoc"
|
|
18
19
|
},
|
|
19
20
|
"dependencies": {
|
|
20
21
|
"@better-auth/api-key": "1.5.4",
|
|
@@ -25,6 +26,8 @@
|
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
27
28
|
"@types/node": "latest",
|
|
29
|
+
"typedoc": "0.28.18",
|
|
30
|
+
"typedoc-plugin-markdown": "4.11.0",
|
|
28
31
|
"typescript": "5.9.2",
|
|
29
32
|
"unbuild": "3.6.1"
|
|
30
33
|
}
|