diff --git a/package.json b/package.json index f9faf16..b6bc1a7 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "type": "git", "url": "https://github.com/PropelAuth/node-apis" }, - "version": "2.1.34", + "version": "2.1.35", "license": "MIT", "keywords": [ "auth", diff --git a/src/api.ts b/src/api.ts index 511d6e4..85da54e 100644 --- a/src/api.ts +++ b/src/api.ts @@ -16,23 +16,15 @@ import { importApiKey, ApiKeysImportRequest, ApiKeysImportResponse, - validateImportedApiKey + validateImportedApiKey, } from "./api/endUserApiKeys" import { StepUpMfaVerifyTotpResponse, VerifyTotpChallengeRequest, verifyStepUpTotpChallenge, } from "./api/mfa/verifyTotp" -import { - sendSmsMfaCode, - SendSmsMfaCodeRequestResponse, - SendSmsMfaCodeRequest -} from "./api/mfa/sendSmsMfaCode" -import { - verifySmsChallenge, - VerifySmsChallengeRequest, - VerifySmsChallengeResponse -} from "./api/mfa/verifySmsChallenge" +import { sendSmsMfaCode, SendSmsMfaCodeRequestResponse, SendSmsMfaCodeRequest } from "./api/mfa/sendSmsMfaCode" +import { verifySmsChallenge, VerifySmsChallengeRequest, VerifySmsChallengeResponse } from "./api/mfa/verifySmsChallenge" import { StepUpMfaVerifyGrantResponse, VerifyStepUpGrantRequest, verifyStepUpGrant } from "./api/mfa/verifyGrant" import { createMagicLink, CreateMagicLinkRequest, MagicLink } from "./api/magicLink" import { fetchEmployeeById, Employee } from "./api/employee" @@ -62,6 +54,7 @@ import { FetchPendingInvitesParams, fetchSamlSpMetadata, FetchSamlSpMetadataResponse, + migrateOrgToIsolated, OrgQuery, OrgQueryResponse, PendingInvitesPage, @@ -114,7 +107,7 @@ import { MfaPhoneType, MfaPhones, MfaTotpType, - FetchUserMfaMethodsResponse + FetchUserMfaMethodsResponse, } from "./api/user" import { CustomRoleMappings } from "./customRoleMappings" import { @@ -140,18 +133,36 @@ export function getApis(authUrl: URL, integrationApiKey: string) { return fetchUserMetadataByUserIdWithIdCheck(authUrl, integrationApiKey, userId, includeOrgs) } - function fetchUserMetadataByEmail(email: string, includeOrgs?: boolean): Promise { - return fetchUserMetadataByQuery(authUrl, integrationApiKey, "email", { + function fetchUserMetadataByEmail( + email: string, + includeOrgs?: boolean, + isolatedOrgId?: string + ): Promise { + const params: any = { email: email, include_orgs: includeOrgs || false, - }) + } + + if (isolatedOrgId) { + params.isolated_org_id = isolatedOrgId + } + return fetchUserMetadataByQuery(authUrl, integrationApiKey, "email", params) } - function fetchUserMetadataByUsername(username: string, includeOrgs?: boolean): Promise { - return fetchUserMetadataByQuery(authUrl, integrationApiKey, "username", { + function fetchUserMetadataByUsername( + username: string, + includeOrgs?: boolean, + isolatedOrgId?: string + ): Promise { + const params: any = { username: username, include_orgs: includeOrgs || false, - }) + } + + if (isolatedOrgId) { + params.isolated_org_id = isolatedOrgId + } + return fetchUserMetadataByQuery(authUrl, integrationApiKey, "username", params) } function fetchBatchUserMetadataByUserIds( @@ -359,7 +370,9 @@ export function getApis(authUrl: URL, integrationApiKey: string) { return inviteUserToOrg(authUrl, integrationApiKey, inviteUserToOrgRequest) } - function inviteUserToOrgByUserIdWrapper(inviteUserToOrgByUserIdRequest: InviteUserToOrgByUserIdRequest): Promise { + function inviteUserToOrgByUserIdWrapper( + inviteUserToOrgByUserIdRequest: InviteUserToOrgByUserIdRequest + ): Promise { return inviteUserToOrgByUserId(authUrl, integrationApiKey, inviteUserToOrgByUserIdRequest) } @@ -377,6 +390,12 @@ export function getApis(authUrl: URL, integrationApiKey: string) { return revokePendingOrgInvite(authUrl, integrationApiKey, revokePendingOrgInviteRequest) } + function migrateOrgToIsolatedWrapper( + orgId: string + ): Promise { + return migrateOrgToIsolated(authUrl, integrationApiKey, orgId) + } + // end user api key wrappers function fetchApiKeyWrapper(apiKeyId: string): Promise { return fetchApiKey(authUrl, integrationApiKey, apiKeyId) @@ -426,27 +445,19 @@ export function getApis(authUrl: URL, integrationApiKey: string) { return verifyStepUpGrant(authUrl, integrationApiKey, verifyStepUpGrantRequest) } - function fetchApiKeyUsageWrapper( - apiKeyUsageQuery: ApiKeyUsageQueryRequest - ): Promise { + function fetchApiKeyUsageWrapper(apiKeyUsageQuery: ApiKeyUsageQueryRequest): Promise { return fetchApiKeyUsage(authUrl, integrationApiKey, apiKeyUsageQuery) } - function importApiKeyWrapper( - apiKeysImportRequest: ApiKeysImportRequest - ): Promise { + function importApiKeyWrapper(apiKeysImportRequest: ApiKeysImportRequest): Promise { return importApiKey(authUrl, integrationApiKey, apiKeysImportRequest) } - function validateImportedApiKeyWrapper( - apiKeyToken: string - ): Promise { + function validateImportedApiKeyWrapper(apiKeyToken: string): Promise { return validateImportedApiKey(authUrl, integrationApiKey, apiKeyToken) } - function fetchUserMfaMethodsWrapper( - userId: string - ): Promise { + function fetchUserMfaMethodsWrapper(userId: string): Promise { return fetchUserMfaMethods(authUrl, integrationApiKey, userId) } @@ -516,6 +527,8 @@ export function getApis(authUrl: URL, integrationApiKey: string) { setSamlIdpMetadata: setSamlIdpMetadataWrapper, samlGoLive: samlGoLiveWrapper, deleteSamlConnection: deleteSamlConnectionWrapper, + migrateOrgToIsolated: migrateOrgToIsolatedWrapper, + // api keys functions fetchApiKey: fetchApiKeyWrapper, fetchCurrentApiKeys: fetchCurrentApiKeysWrapper, diff --git a/src/api/org.ts b/src/api/org.ts index ce79cd2..17e16a5 100644 --- a/src/api/org.ts +++ b/src/api/org.ts @@ -7,6 +7,7 @@ import { RemoveUserFromOrgException, RevokePendingOrgInviteException, UpdateOrgException, + MigrateOrgToIsolatedException } from "../exceptions" import { httpRequest } from "../http" import { CreatedOrg, Org, Organization } from "../user" @@ -577,6 +578,7 @@ export type UpdateOrgRequest = { legacyOrgId?: string require2faBy?: string extraDomains?: string[] + ssoTrustLevel?: "AlwaysTrust" | "NeverTrust" | "TrustForDomain" } export function updateOrg( @@ -599,6 +601,7 @@ export function updateOrg( legacy_org_id: updateOrgRequest.legacyOrgId, require_2fa_by: updateOrgRequest.require2faBy, extra_domains: updateOrgRequest.extraDomains, + sso_trust_level: updateOrgRequest.ssoTrustLevel } return httpRequest( authUrl, @@ -743,3 +746,34 @@ export function deleteSamlConnection( return true }) } + +export function migrateOrgToIsolated( + authUrl: URL, + integrationApiKey: string, + orgId: string +): Promise { + const request = { + org_id: orgId, + } + return httpRequest( + authUrl, + integrationApiKey, + `${BASE_ENDPOINT_PATH}/isolate_org`, + "POST", + JSON.stringify(request) + ).then((httpResponse) => { + if (httpResponse.statusCode === 401) { + throw new Error("integrationApiKey is incorrect") + } else if (httpResponse.statusCode === 429) { + throw new RateLimitedException(httpResponse.response) + } else if (httpResponse.statusCode === 400) { + throw new MigrateOrgToIsolatedException(httpResponse.response) + } else if (httpResponse.statusCode === 404) { + return false + } else if (httpResponse.statusCode && httpResponse.statusCode >= 400) { + throw new Error("Unknown error when migrating org to isolated") + } + + return true + }) +} diff --git a/src/api/user.ts b/src/api/user.ts index 495d53b..deb3c80 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -19,6 +19,7 @@ export type UsersQuery = { emailOrUsername?: string includeOrgs?: boolean legacyUserId?: string + isolatedOrgId?: string } export type UsersPagedResponse = { @@ -100,6 +101,7 @@ export function fetchUsersByQuery( email_or_username: query.emailOrUsername, include_orgs: query.includeOrgs, legacy_user_id: query.legacyUserId, + isolated_org_id: query.isolatedOrgId } const q = formatQueryParameters(queryParams) return httpRequest(authUrl, integrationApiKey, `${ENDPOINT_PATH}/query?${q}`, "GET").then((httpResponse) => { diff --git a/src/exceptions.ts b/src/exceptions.ts index 20b2606..3e34489 100644 --- a/src/exceptions.ts +++ b/src/exceptions.ts @@ -46,6 +46,14 @@ export class ChangeUserRoleInOrgException extends Error { } } +export class MigrateOrgToIsolatedException extends Error { + readonly fieldToErrors: { [fieldName: string]: string[] } + constructor(message: string) { + super(message) + this.fieldToErrors = JSON.parse(message) + } +} + export class RemoveUserFromOrgException extends Error { readonly fieldToErrors: { [fieldName: string]: string[] } constructor(message: string) { diff --git a/src/index.ts b/src/index.ts index 4f43c66..67c58e4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -76,6 +76,7 @@ export { MfaNotEnabledException, IncorrectMfaCodeException, RevokePendingOrgInviteException, + MigrateOrgToIsolatedException } from "./exceptions" export type { SocialLoginProvider, SamlLoginProvider, LoginMethod } from "./loginMethod" export type { CustomRoleMappings, CustomRoleMapping } from "./customRoleMappings" diff --git a/src/user.ts b/src/user.ts index e27b910..66fd78c 100644 --- a/src/user.ts +++ b/src/user.ts @@ -159,6 +159,7 @@ export type Org = { legacyOrgId?: string metadata: { [key: string]: any } customRoleMappingName?: string + isolated: boolean } export type Organization = { @@ -176,6 +177,7 @@ export type Organization = { domainRestrict: boolean customRoleMappingName?: string legacyOrgId?: string + isolated: boolean } export type CreatedOrg = { @@ -215,6 +217,7 @@ export type UserMetadata = { impersonatorUserId?: string metadata?: { [key: string]: any } properties?: { [key: string]: unknown } + isolatedOrgId?: string } export class OrgMemberInfo {