@drmhse/sso-sdk 0.3.14 → 0.5.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/dist/index.mjs CHANGED
@@ -3,23 +3,38 @@ var AuthErrorCodes = /* @__PURE__ */ ((AuthErrorCodes2) => {
3
3
  AuthErrorCodes2["MFA_REQUIRED"] = "MFA_REQUIRED";
4
4
  AuthErrorCodes2["ORG_REQUIRED"] = "ORG_REQUIRED";
5
5
  AuthErrorCodes2["INVALID_CREDENTIALS"] = "INVALID_CREDENTIALS";
6
- AuthErrorCodes2["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
7
6
  AuthErrorCodes2["REFRESH_TOKEN_INVALID"] = "REFRESH_TOKEN_INVALID";
7
+ AuthErrorCodes2["NOT_FOUND"] = "NOT_FOUND";
8
8
  AuthErrorCodes2["UNAUTHORIZED"] = "UNAUTHORIZED";
9
9
  AuthErrorCodes2["FORBIDDEN"] = "FORBIDDEN";
10
- AuthErrorCodes2["NOT_FOUND"] = "NOT_FOUND";
10
+ AuthErrorCodes2["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
11
11
  AuthErrorCodes2["VALIDATION_ERROR"] = "VALIDATION_ERROR";
12
12
  AuthErrorCodes2["EMAIL_ALREADY_EXISTS"] = "EMAIL_ALREADY_EXISTS";
13
13
  AuthErrorCodes2["EMAIL_NOT_VERIFIED"] = "EMAIL_NOT_VERIFIED";
14
14
  AuthErrorCodes2["ACCOUNT_SUSPENDED"] = "ACCOUNT_SUSPENDED";
15
15
  AuthErrorCodes2["ORG_SUSPENDED"] = "ORG_SUSPENDED";
16
- AuthErrorCodes2["RATE_LIMITED"] = "RATE_LIMITED";
17
- AuthErrorCodes2["WEAK_PASSWORD"] = "WEAK_PASSWORD";
18
- AuthErrorCodes2["INVALID_MFA_CODE"] = "INVALID_MFA_CODE";
16
+ AuthErrorCodes2["BAD_REQUEST"] = "BAD_REQUEST";
17
+ AuthErrorCodes2["DUPLICATE_CONSTRAINT"] = "DUPLICATE_CONSTRAINT";
18
+ AuthErrorCodes2["ORGANIZATION_NOT_ACTIVE"] = "ORGANIZATION_NOT_ACTIVE";
19
+ AuthErrorCodes2["SERVICE_LIMIT_EXCEEDED"] = "SERVICE_LIMIT_EXCEEDED";
20
+ AuthErrorCodes2["TEAM_LIMIT_EXCEEDED"] = "TEAM_LIMIT_EXCEEDED";
21
+ AuthErrorCodes2["INVITATION_EXPIRED"] = "INVITATION_EXPIRED";
19
22
  AuthErrorCodes2["LINK_EXPIRED"] = "LINK_EXPIRED";
20
23
  AuthErrorCodes2["DEVICE_CODE_EXPIRED"] = "DEVICE_CODE_EXPIRED";
21
24
  AuthErrorCodes2["AUTHORIZATION_PENDING"] = "AUTHORIZATION_PENDING";
25
+ AuthErrorCodes2["DEVICE_CODE_PENDING"] = "DEVICE_CODE_PENDING";
26
+ AuthErrorCodes2["FEATURE_NOT_AVAILABLE_IN_TIER"] = "FEATURE_NOT_AVAILABLE_IN_TIER";
27
+ AuthErrorCodes2["RATE_LIMITED"] = "RATE_LIMITED";
28
+ AuthErrorCodes2["TOO_MANY_REQUESTS"] = "TOO_MANY_REQUESTS";
29
+ AuthErrorCodes2["WEAK_PASSWORD"] = "WEAK_PASSWORD";
30
+ AuthErrorCodes2["INVALID_MFA_CODE"] = "INVALID_MFA_CODE";
31
+ AuthErrorCodes2["JWT_ERROR"] = "JWT_ERROR";
32
+ AuthErrorCodes2["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
33
+ AuthErrorCodes2["OAUTH_ERROR"] = "OAUTH_ERROR";
22
34
  AuthErrorCodes2["PASSKEY_ERROR"] = "PASSKEY_ERROR";
35
+ AuthErrorCodes2["STRIPE_ERROR"] = "STRIPE_ERROR";
36
+ AuthErrorCodes2["DATABASE_ERROR"] = "DATABASE_ERROR";
37
+ AuthErrorCodes2["GENERIC_ERROR"] = "GENERIC_ERROR";
23
38
  return AuthErrorCodes2;
24
39
  })(AuthErrorCodes || {});
25
40
  var SsoApiError = class _SsoApiError extends Error {
@@ -229,10 +244,13 @@ var HttpClient = class {
229
244
  /**
230
245
  * DELETE request
231
246
  */
232
- async delete(path, config) {
247
+ async delete(path, data, config) {
248
+ const requestConfig = data && typeof data === "object" && "headers" in data && !config ? data : config;
249
+ const body = requestConfig === data ? void 0 : data;
233
250
  return this.request(path, {
234
251
  method: "DELETE",
235
- headers: config?.headers
252
+ body,
253
+ headers: requestConfig?.headers
236
254
  });
237
255
  }
238
256
  };
@@ -815,7 +833,7 @@ var AuthModule = class {
815
833
  }
816
834
  /**
817
835
  * Login with email and password.
818
- * Automatically persists the session and configures the client.
836
+ * Automatically persists the session once authentication is complete.
819
837
  *
820
838
  * @param payload Login credentials (email and password)
821
839
  * @returns Access token, refresh token, and expiration info
@@ -826,15 +844,17 @@ var AuthModule = class {
826
844
  * email: 'user@example.com',
827
845
  * password: 'SecurePassword123!'
828
846
  * });
829
- * // Session is automatically saved - no need for manual token management
847
+ * // Session is automatically saved unless MFA is required
830
848
  * ```
831
849
  */
832
850
  async login(payload) {
833
851
  const response = await this.http.post("/api/auth/login", payload);
834
- await this.session.setSession({
835
- access_token: response.data.access_token,
836
- refresh_token: response.data.refresh_token
837
- });
852
+ if (response.data.refresh_token) {
853
+ await this.session.setSession({
854
+ access_token: response.data.access_token,
855
+ refresh_token: response.data.refresh_token
856
+ });
857
+ }
838
858
  return response.data;
839
859
  }
840
860
  /**
@@ -963,6 +983,20 @@ var AuthModule = class {
963
983
  });
964
984
  return response.data;
965
985
  }
986
+ /**
987
+ * Fetch public hosted-auth context for an organization/service login.
988
+ */
989
+ async getContext(params = {}) {
990
+ const searchParams = new URLSearchParams();
991
+ if (params.org) searchParams.append("org", params.org);
992
+ if (params.service) searchParams.append("service", params.service);
993
+ if (params.redirect_uri) searchParams.append("redirect_uri", params.redirect_uri);
994
+ const query = searchParams.toString();
995
+ const response = await this.http.get(
996
+ `/api/auth/context${query ? `?${query}` : ""}`
997
+ );
998
+ return response.data;
999
+ }
966
1000
  };
967
1001
 
968
1002
  // src/modules/user.ts
@@ -1017,6 +1051,41 @@ var IdentitiesModule = class {
1017
1051
  await this.http.delete(`/api/user/identities/${provider}`);
1018
1052
  }
1019
1053
  };
1054
+ var LinkedAccountsModule = class {
1055
+ constructor(http) {
1056
+ this.http = http;
1057
+ }
1058
+ async list() {
1059
+ const response = await this.http.get("/api/user/linked-accounts");
1060
+ return response.data;
1061
+ }
1062
+ async startLink(provider) {
1063
+ const response = await this.http.post(`/api/user/linked-accounts/${provider}/link`, {});
1064
+ return response.data;
1065
+ }
1066
+ async grant(accountId, payload) {
1067
+ const response = await this.http.post(`/api/user/linked-accounts/${accountId}/grants`, payload);
1068
+ return response.data;
1069
+ }
1070
+ async revokeGrant(accountId, serviceId) {
1071
+ await this.http.delete(`/api/user/linked-accounts/${accountId}/grants/${serviceId}`);
1072
+ }
1073
+ async unlink(accountId) {
1074
+ await this.http.delete(`/api/user/linked-accounts/${accountId}`);
1075
+ }
1076
+ async getProviderTokenRequest(state) {
1077
+ const response = await this.http.get(`/api/user/provider-token-requests/${state}`);
1078
+ return response.data;
1079
+ }
1080
+ async completeProviderTokenRequest(state, payload = {}) {
1081
+ const response = await this.http.post(`/api/user/provider-token-requests/${state}/complete`, payload);
1082
+ return response.data;
1083
+ }
1084
+ async startProviderTokenRequestLink(state) {
1085
+ const response = await this.http.post(`/api/user/provider-token-requests/${state}/link`, {});
1086
+ return response.data;
1087
+ }
1088
+ };
1020
1089
  var MfaModule = class {
1021
1090
  constructor(http) {
1022
1091
  this.http = http;
@@ -1218,6 +1287,7 @@ var UserModule = class {
1218
1287
  constructor(http) {
1219
1288
  this.http = http;
1220
1289
  this.identities = new IdentitiesModule(http);
1290
+ this.linkedAccounts = new LinkedAccountsModule(http);
1221
1291
  this.mfa = new MfaModule(http);
1222
1292
  this.devices = new DevicesModule(http);
1223
1293
  }
@@ -1588,6 +1658,76 @@ var WebhooksModule = class {
1588
1658
  }
1589
1659
  };
1590
1660
 
1661
+ // src/modules/organizations/upstream-providers.ts
1662
+ var UpstreamProvidersModule = class {
1663
+ constructor(http) {
1664
+ this.http = http;
1665
+ }
1666
+ /**
1667
+ * List all upstream providers for an organization.
1668
+ *
1669
+ * @param orgSlug Organization slug
1670
+ * @returns Array of upstream providers
1671
+ */
1672
+ async list(orgSlug) {
1673
+ const response = await this.http.get(
1674
+ `/api/organizations/${orgSlug}/upstream-providers`
1675
+ );
1676
+ return response.data;
1677
+ }
1678
+ /**
1679
+ * Get a specific upstream provider.
1680
+ *
1681
+ * @param orgSlug Organization slug
1682
+ * @param providerId Provider ID or connection_id
1683
+ * @returns Upstream provider details
1684
+ */
1685
+ async get(orgSlug, providerId) {
1686
+ const response = await this.http.get(
1687
+ `/api/organizations/${orgSlug}/upstream-providers/${providerId}`
1688
+ );
1689
+ return response.data;
1690
+ }
1691
+ /**
1692
+ * Create a new upstream provider.
1693
+ *
1694
+ * @param orgSlug Organization slug
1695
+ * @param payload Provider configuration
1696
+ * @returns Created upstream provider
1697
+ */
1698
+ async create(orgSlug, payload) {
1699
+ const response = await this.http.post(
1700
+ `/api/organizations/${orgSlug}/upstream-providers`,
1701
+ payload
1702
+ );
1703
+ return response.data;
1704
+ }
1705
+ /**
1706
+ * Update an existing upstream provider.
1707
+ *
1708
+ * @param orgSlug Organization slug
1709
+ * @param providerId Provider ID or connection_id
1710
+ * @param payload Update payload
1711
+ * @returns Updated upstream provider
1712
+ */
1713
+ async update(orgSlug, providerId, payload) {
1714
+ const response = await this.http.patch(
1715
+ `/api/organizations/${orgSlug}/upstream-providers/${providerId}`,
1716
+ payload
1717
+ );
1718
+ return response.data;
1719
+ }
1720
+ /**
1721
+ * Delete an upstream provider.
1722
+ *
1723
+ * @param orgSlug Organization slug
1724
+ * @param providerId Provider ID or connection_id
1725
+ */
1726
+ async delete(orgSlug, providerId) {
1727
+ await this.http.delete(`/api/organizations/${orgSlug}/upstream-providers/${providerId}`);
1728
+ }
1729
+ };
1730
+
1591
1731
  // src/modules/organizations.ts
1592
1732
  var OrganizationsModule = class {
1593
1733
  constructor(http) {
@@ -1667,7 +1807,9 @@ var OrganizationsModule = class {
1667
1807
  payload
1668
1808
  );
1669
1809
  const invitation = response.data;
1670
- await this.http.post("/api/invitations/accept", { token: invitation.token });
1810
+ await this.http.post(
1811
+ `/api/organizations/${orgSlug}/invitations/${invitation.id}/accept`
1812
+ );
1671
1813
  return invitation;
1672
1814
  },
1673
1815
  /**
@@ -1708,6 +1850,25 @@ var OrganizationsModule = class {
1708
1850
  remove: async (orgSlug, userId) => {
1709
1851
  await this.http.post(`/api/organizations/${orgSlug}/members/${userId}`);
1710
1852
  },
1853
+ /**
1854
+ * List a member's direct per-service access grants.
1855
+ */
1856
+ listServiceAccess: async (orgSlug, userId) => {
1857
+ const response = await this.http.get(
1858
+ `/api/organizations/${orgSlug}/members/${userId}/service-access`
1859
+ );
1860
+ return response.data;
1861
+ },
1862
+ /**
1863
+ * Replace a member's direct per-service access grants.
1864
+ */
1865
+ updateServiceAccess: async (orgSlug, userId, payload) => {
1866
+ const response = await this.http.put(
1867
+ `/api/organizations/${orgSlug}/members/${userId}/service-access`,
1868
+ payload
1869
+ );
1870
+ return response.data;
1871
+ },
1711
1872
  /**
1712
1873
  * Transfer organization ownership to another member.
1713
1874
  * Requires 'owner' role.
@@ -2272,6 +2433,7 @@ var OrganizationsModule = class {
2272
2433
  };
2273
2434
  this.auditLogs = new AuditLogsModule(http);
2274
2435
  this.webhooks = new WebhooksModule(http);
2436
+ this.upstreamProviders = new UpstreamProvidersModule(http);
2275
2437
  }
2276
2438
  /**
2277
2439
  * Create a new organization (requires authentication).
@@ -3136,13 +3298,12 @@ var ServicesModule = class {
3136
3298
  *
3137
3299
  * @param orgSlug Organization slug
3138
3300
  * @param serviceSlug Service slug
3139
- * @returns Service with provider grants and plans
3301
+ * @returns Service details
3140
3302
  *
3141
3303
  * @example
3142
3304
  * ```typescript
3143
3305
  * const service = await sso.services.get('acme-corp', 'main-app');
3144
- * console.log(service.service.redirect_uris);
3145
- * console.log(service.plans);
3306
+ * console.log(service.name, service.client_id);
3146
3307
  * ```
3147
3308
  */
3148
3309
  async get(orgSlug, serviceSlug) {
@@ -3190,6 +3351,17 @@ var ServicesModule = class {
3190
3351
  async delete(orgSlug, serviceSlug) {
3191
3352
  await this.http.delete(`/api/organizations/${orgSlug}/services/${serviceSlug}`);
3192
3353
  }
3354
+ /**
3355
+ * Rotate a service client secret.
3356
+ * The new secret is returned once and cannot be retrieved later.
3357
+ */
3358
+ async rotateSecret(orgSlug, serviceSlug) {
3359
+ const response = await this.http.post(
3360
+ `/api/organizations/${orgSlug}/services/${serviceSlug}/secret/rotate`,
3361
+ {}
3362
+ );
3363
+ return response.data;
3364
+ }
3193
3365
  };
3194
3366
 
3195
3367
  // src/modules/invitations.ts
@@ -3285,6 +3457,14 @@ var InvitationsModule = class {
3285
3457
  const payload = { token };
3286
3458
  await this.http.post("/api/invitations/accept", payload);
3287
3459
  }
3460
+ /**
3461
+ * Accept one of the current user's invitations by invitation ID.
3462
+ *
3463
+ * @param invitationId Invitation ID
3464
+ */
3465
+ async acceptById(invitationId) {
3466
+ await this.http.post(`/api/invitations/${invitationId}/accept`);
3467
+ }
3288
3468
  /**
3289
3469
  * Decline an invitation using its token.
3290
3470
  *
@@ -3299,6 +3479,14 @@ var InvitationsModule = class {
3299
3479
  const payload = { token };
3300
3480
  await this.http.post("/api/invitations/decline", payload);
3301
3481
  }
3482
+ /**
3483
+ * Decline one of the current user's invitations by invitation ID.
3484
+ *
3485
+ * @param invitationId Invitation ID
3486
+ */
3487
+ async declineById(invitationId) {
3488
+ await this.http.post(`/api/invitations/${invitationId}/decline`);
3489
+ }
3302
3490
  };
3303
3491
 
3304
3492
  // src/modules/platform.ts
@@ -3519,6 +3707,13 @@ var PlatformModule = class {
3519
3707
  const response = await this.http.get("/api/platform/users", { params: options });
3520
3708
  return response.data;
3521
3709
  },
3710
+ /**
3711
+ * Get a single platform user by ID.
3712
+ */
3713
+ get: async (userId) => {
3714
+ const response = await this.http.get(`/api/platform/users/${userId}`);
3715
+ return response.data;
3716
+ },
3522
3717
  /**
3523
3718
  * Search users by email address or user ID.
3524
3719
  *
@@ -3777,6 +3972,13 @@ var PlatformModule = class {
3777
3972
  const response = await this.http.post("/api/platform/impersonate", payload);
3778
3973
  return response.data;
3779
3974
  }
3975
+ /**
3976
+ * Get platform operational counters for jobs, webhooks, and SIEM delivery.
3977
+ */
3978
+ async getOperationsStatus() {
3979
+ const response = await this.http.get("/api/platform/operations/status");
3980
+ return response.data;
3981
+ }
3780
3982
  };
3781
3983
 
3782
3984
  // src/modules/serviceApi.ts
@@ -3856,6 +4058,17 @@ var ServiceApiModule = class {
3856
4058
  const response = await this.http.get("/api/service/info");
3857
4059
  return response.data;
3858
4060
  }
4061
+ /**
4062
+ * Request a backend-only third-party provider access token for an AuthOS user.
4063
+ * Requires `read:provider_tokens` or `read:provider_tokens:{provider}` on the API key.
4064
+ */
4065
+ async requestProviderToken(request) {
4066
+ const response = await this.http.post("/api/service/provider-tokens", {
4067
+ ...request,
4068
+ scopes: request.scopes ?? []
4069
+ });
4070
+ return response.data;
4071
+ }
3859
4072
  /**
3860
4073
  * Create a new user
3861
4074
  * Requires 'write:users' permission on the API key
@@ -4290,6 +4503,29 @@ var PasskeysModule = class {
4290
4503
  );
4291
4504
  return response.data;
4292
4505
  }
4506
+ /**
4507
+ * List registered passkeys for the authenticated user.
4508
+ */
4509
+ async list() {
4510
+ const response = await this.http.get("/api/auth/passkeys");
4511
+ return response.data;
4512
+ }
4513
+ /**
4514
+ * Rename a passkey for the authenticated user.
4515
+ */
4516
+ async updateName(passkeyId, name) {
4517
+ const response = await this.http.patch(`/api/auth/passkeys/${passkeyId}`, {
4518
+ name
4519
+ });
4520
+ return response.data;
4521
+ }
4522
+ /**
4523
+ * Delete a passkey for the authenticated user.
4524
+ */
4525
+ async delete(passkeyId) {
4526
+ const response = await this.http.delete(`/api/auth/passkeys/${passkeyId}`);
4527
+ return response.data;
4528
+ }
4293
4529
  /**
4294
4530
  * Finish the passkey registration ceremony.
4295
4531
  * Verifies the credential created by the browser.
@@ -4375,10 +4611,10 @@ var PasskeysModule = class {
4375
4611
  * Start the passkey authentication ceremony.
4376
4612
  * Returns the options required to get credentials from the browser.
4377
4613
  */
4378
- async authenticateStart(email) {
4614
+ async authenticateStart(email, context) {
4379
4615
  const response = await this.http.post(
4380
4616
  "/api/auth/passkeys/authenticate/start",
4381
- { email }
4617
+ { email, ...context }
4382
4618
  );
4383
4619
  return response.data;
4384
4620
  }
@@ -4400,11 +4636,11 @@ var PasskeysModule = class {
4400
4636
  * Authenticate with a passkey and obtain a JWT token
4401
4637
  * ...
4402
4638
  */
4403
- async login(email) {
4639
+ async login(email, context) {
4404
4640
  if (!this.isSupported()) {
4405
4641
  throw new Error("WebAuthn is not supported in this browser");
4406
4642
  }
4407
- const startData = await this.authenticateStart(email);
4643
+ const startData = await this.authenticateStart(email, context);
4408
4644
  const getOptions = {
4409
4645
  publicKey: {
4410
4646
  ...startData.options,
@@ -4475,7 +4711,10 @@ var MagicLinks = class {
4475
4711
  * @returns Promise resolving to magic link response
4476
4712
  */
4477
4713
  async request(data) {
4478
- const response = await this.http.post("/api/auth/magic-link/request", data);
4714
+ const response = await this.http.post("/api/auth/magic-link/request", {
4715
+ ...data,
4716
+ org_slug: data.org_slug || data.orgSlug
4717
+ });
4479
4718
  return response.data;
4480
4719
  }
4481
4720
  /**
@@ -4507,7 +4746,8 @@ var MagicLinks = class {
4507
4746
  if (redirectUri) {
4508
4747
  params.append("redirect_uri", redirectUri);
4509
4748
  }
4510
- return this.http.get(`/api/auth/magic-link/verify?${params.toString()}`);
4749
+ const response = await this.http.get(`/api/auth/magic-link/verify?${params.toString()}`);
4750
+ return response.data;
4511
4751
  }
4512
4752
  /**
4513
4753
  * Construct the complete magic link URL that would be sent via email
@@ -4564,8 +4804,11 @@ var PrivacyModule = class {
4564
4804
  * // "User data has been anonymized. PII has been removed while preserving audit logs."
4565
4805
  * ```
4566
4806
  */
4567
- async forgetUser(userId) {
4568
- const response = await this.http.delete(`/api/privacy/forget/${userId}`);
4807
+ async forgetUser(userId, payload = {}) {
4808
+ const response = await this.http.delete(
4809
+ `/api/privacy/forget/${userId}`,
4810
+ payload
4811
+ );
4569
4812
  return response.data;
4570
4813
  }
4571
4814
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drmhse/sso-sdk",
3
- "version": "0.3.14",
3
+ "version": "0.5.0",
4
4
  "description": "Zero-dependency TypeScript SDK for AuthOS, the multi-tenant authentication platform",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",