UNPKG

@authup/core-kit

Version:

Package containing global constants, types & interfaces.

1,068 lines (1,023 loc) 39.9 kB
import { AuthupError, ErrorCode } from '@authup/errors'; import { createValidator } from '@validup/adapter-zod'; import { Container } from 'validup'; import zod, { z } from 'zod'; import { DecisionStrategy } from '@authup/kit'; /* * Copyright (c) 2025. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var ValidatorGroup = /*#__PURE__*/ function(ValidatorGroup) { ValidatorGroup["CREATE"] = "create"; ValidatorGroup["UPDATE"] = "update"; return ValidatorGroup; }({}); class ClientError extends AuthupError { static credentialsInvalid() { return new ClientError({ code: ErrorCode.ENTITY_CREDENTIALS_INVALID, message: 'The client credentials are invalid.' }); } static invalid() { return new ClientError({ code: ErrorCode.OAUTH_CLIENT_INVALID, message: 'The client is invalid.' }); } static notFound() { return new ClientError({ code: ErrorCode.ENTITY_NOT_FOUND, message: 'The client account was not found.' }); } static inactive() { return new ClientError({ code: ErrorCode.ENTITY_INACTIVE, message: 'The client account is inactive.' }); } } function isNameValid(input, options = {}) { if (/\s/g.test(input)) { if (options.throwOnFailure) { throw new AuthupError('Whitespace character is not allowed.'); } return false; } if (/^[A-Za-z0-9-_.]+$/.test(input)) { return true; } if (options.throwOnFailure) { throw new AuthupError('Only the characters [A-Za-z0-9-_.]+ are allowed.'); } return false; } function isClientNameValid(name, options = {}) { return isNameValid(name, options); } class ClientValidator extends Container { initialize() { super.initialize(); // ---------------------------------------------- this.mount('active', { optional: true }, createValidator(z.boolean())); this.mount('is_confidential', { optional: true }, createValidator(z.boolean())); // ---------------------------------------------- const nameValidator = createValidator(z.string().min(3).max(128).check((ctx)=>{ try { isClientNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The client name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('display_name', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('description', { optional: true }, createValidator(z.string().min(3).max(4096).nullable())); // ---------------------------------------------- this.mount('secret', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('secret_encrypted', { optional: true }, createValidator(z.boolean())); this.mount('secret_hashed', { optional: true }, createValidator(z.boolean())); // ---------------------------------------------- this.mount('redirect_uri', { optional: true }, createValidator(z.string().check((ctx)=>{ const validator = z.url(); const urls = ctx.value.split(','); for (const url of urls){ try { validator.parse(url); } catch (e) { ctx.issues.push({ input: url, code: 'custom', message: e instanceof Error ? e.message : 'The redirect_uri is not valid.' }); } } }).nullable())); this.mount('base_url', { optional: true }, createValidator(z.url().nullable())); this.mount('root_url', { optional: true }, createValidator(z.url().nullable())); this.mount('grant_types', { optional: true }, createValidator(z.string().min(3).max(512).nullable())); this.mount('scope', { optional: true }, createValidator(z.string().min(3).max(512).nullable())); // ---------------------------------------------- this.mount('realm_id', { group: ValidatorGroup.CREATE, optional: true }, createValidator(z.uuid())); } } /* * Copyright (c) 2025. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var IdentityType = /*#__PURE__*/ function(IdentityType) { IdentityType["CLIENT"] = "client"; IdentityType["ROBOT"] = "robot"; IdentityType["USER"] = "user"; return IdentityType; }({}); /* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var IdentityProviderProtocol = /*#__PURE__*/ function(IdentityProviderProtocol) { IdentityProviderProtocol["LDAP"] = "ldap"; IdentityProviderProtocol["OAUTH2"] = "oauth2"; IdentityProviderProtocol["OIDC"] = "oidc"; return IdentityProviderProtocol; }({}); var IdentityProviderMappingSyncMode = /*#__PURE__*/ function(IdentityProviderMappingSyncMode) { /** * Synchronize on initial user login. */ IdentityProviderMappingSyncMode["ONCE"] = "once"; /** * Synchronize on every user login. */ IdentityProviderMappingSyncMode["ALWAYS"] = "always"; /** * Synchronize based on idp configuration. */ IdentityProviderMappingSyncMode["INHERIT"] = "inherit"; return IdentityProviderMappingSyncMode; }({}); function isLdapIdentityProvider(input) { return input.protocol === IdentityProviderProtocol.LDAP; } class IdentityProviderLDAPAttributesValidator extends Container { initialize() { super.initialize(); this.mount('protocol', createValidator(z.string().check((ctx)=>{ if (ctx.value !== IdentityProviderProtocol.LDAP) { ctx.issues.push({ input: ctx.value, code: 'custom', message: 'The protocol should be LDAP.' }); } }))); this.mount('url', createValidator(z.url())); this.mount('timeout', { optional: true }, createValidator(z.number().min(0).optional().nullable())); this.mount('start_tls', { optional: true }, createValidator(z.boolean().optional().nullable())); this.mount('tls', { optional: true }, createValidator(z.any().optional().nullable())); this.mount('base_dn', { optional: true }, createValidator(z.string().min(3).max(2000).optional().nullable())); this.mount('user', createValidator(z.string().min(3))); this.mount('password', createValidator(z.string().min(3))); this.mount('user_base_dn', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('user_filter', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('user_name_attribute', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('user_mail_attribute', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('user_display_name_attribute', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('group_base_dn', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('group_filter', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('group_name_attribute', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('group_class', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('group_member_attribute', { optional: true }, createValidator(z.string().optional().nullable())); this.mount('group_member_user_attribute', { optional: true }, createValidator(z.string().optional().nullable())); } } function isOAuth2IdentityProvider(input) { return input.protocol === IdentityProviderProtocol.OAUTH2; } /* * Copyright (c) 2023. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var IdentityProviderPreset = /*#__PURE__*/ function(IdentityProviderPreset) { IdentityProviderPreset["FACEBOOK"] = "facebook"; IdentityProviderPreset["GITHUB"] = "github"; IdentityProviderPreset["GITLAB"] = "gitlab"; IdentityProviderPreset["GOOGLE"] = "google"; IdentityProviderPreset["PAYPAL"] = "paypal"; IdentityProviderPreset["INSTAGRAM"] = "instagram"; IdentityProviderPreset["STACKOVERFLOW"] = "stackoverflow"; IdentityProviderPreset["TWITTER"] = "twitter"; return IdentityProviderPreset; }({}); function getIdentityProviderProtocolForPreset(id) { switch(id){ case IdentityProviderPreset.GITHUB: case IdentityProviderPreset.GITLAB: case IdentityProviderPreset.GOOGLE: case IdentityProviderPreset.FACEBOOK: case IdentityProviderPreset.INSTAGRAM: case IdentityProviderPreset.PAYPAL: case IdentityProviderPreset.STACKOVERFLOW: case IdentityProviderPreset.TWITTER: return IdentityProviderProtocol.OIDC; } return null; } class IdentityProviderOAuth2PresetAttributesValidator extends Container { initialize() { super.initialize(); this.mount('preset', createValidator(z.string().check((ctx)=>{ const protocol = getIdentityProviderProtocolForPreset(ctx.value); if (protocol !== IdentityProviderProtocol.OAUTH2 && protocol !== IdentityProviderProtocol.OIDC) { ctx.issues.push({ input: ctx.value, code: 'custom', message: `The resolved protocol should be ${IdentityProviderProtocol.OAUTH2} or ${IdentityProviderProtocol.OIDC}` }); } }))); this.mount('client_id', createValidator(z.string().min(3).max(128))); this.mount('client_secret', { optional: true }, createValidator(z.string().min(3).max(128).optional().nullable())); } } class IdentityProviderOAuth2AttributesValidator extends Container { initialize() { super.initialize(); this.mount('preset', createValidator(z.string().optional().nullable().check((ctx)=>{ let protocol; if (typeof ctx.value === 'string') { protocol = getIdentityProviderProtocolForPreset(ctx.value); } if (typeof protocol === 'string') { ctx.issues.push({ input: ctx.value, code: 'custom', message: 'The preset should not be defined.' }); } }))); this.mount('client_id', createValidator(z.string().min(3).max(128))); this.mount('client_secret', { optional: true }, createValidator(z.string().min(3).max(128).optional().nullable())); this.mount('token_url', createValidator(z.url())); this.mount('token_revoke_url', { optional: true }, createValidator(z.url().optional().nullable())); this.mount('authorize_url', createValidator(z.url())); this.mount('user_info_url', { optional: true }, createValidator(z.url().optional().nullable())); this.mount('scope', createValidator(z.string().min(3).max(2000).optional().nullable())); } } class IdentityProviderAttributesValidator extends Container { constructor(options = {}){ super({ ...options, oneOf: true }); } initialize() { super.initialize(); this.mount(new IdentityProviderLDAPAttributesValidator()); this.mount(new IdentityProviderOAuth2AttributesValidator()); this.mount(new IdentityProviderOAuth2PresetAttributesValidator()); } } function buildIdentityProviderAuthorizeCallbackPath(id) { return `/identity-providers/${id}/authorize-in`; } function buildIdentityProviderAuthorizePath(id) { return `/identity-providers/${id}/authorize-out`; } function isIdentityProviderNameValid(input, options = {}) { return isNameValid(input, options); } function isOpenIDIdentityProvider(input) { return input.protocol === IdentityProviderProtocol.OIDC; } class IdentityProviderValidator extends Container { initialize() { super.initialize(); const nameValidator = createValidator(zod.string().min(3).max(128).check((ctx)=>{ try { isIdentityProviderNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('display_name', { optional: true }, createValidator(zod.string().min(3).max(256))); const enabledValidator = createValidator(zod.boolean()); this.mount('enabled', { group: ValidatorGroup.CREATE }, enabledValidator); this.mount('enabled', { group: ValidatorGroup.UPDATE, optional: true }, enabledValidator); this.mount('realm_id', { group: ValidatorGroup.CREATE, optional: true }, createValidator(zod.uuid())); this.mount('protocol', createValidator(zod.enum(IdentityProviderProtocol))); this.mount('preset', { optional: true }, createValidator(zod.enum(IdentityProviderPreset).optional().nullable())); } } /* * Copyright (c) 2021. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var PermissionName = /*#__PURE__*/ function(PermissionName) { PermissionName["CLIENT_CREATE"] = "client_create"; PermissionName["CLIENT_DELETE"] = "client_delete"; PermissionName["CLIENT_UPDATE"] = "client_update"; PermissionName["CLIENT_READ"] = "client_read"; PermissionName["CLIENT_SELF_MANAGE"] = "client_self_manage"; PermissionName["CLIENT_PERMISSION_CREATE"] = "client_permission_create"; PermissionName["CLIENT_PERMISSION_DELETE"] = "client_permission_delete"; PermissionName["CLIENT_PERMISSION_READ"] = "client_permission_read"; PermissionName["CLIENT_ROLE_CREATE"] = "client_role_create"; PermissionName["CLIENT_ROLE_DELETE"] = "client_role_delete"; PermissionName["CLIENT_ROLE_UPDATE"] = "client_role_update"; PermissionName["CLIENT_ROLE_READ"] = "client_role_read"; PermissionName["CLIENT_SCOPE_CREATE"] = "client_scope_create"; PermissionName["CLIENT_SCOPE_DELETE"] = "client_scope_delete"; PermissionName["IDENTITY_PROVIDER_CREATE"] = "identity_provider_create"; PermissionName["IDENTITY_PROVIDER_DELETE"] = "identity_provider_delete"; PermissionName["IDENTITY_PROVIDER_UPDATE"] = "identity_provider_update"; PermissionName["IDENTITY_PROVIDER_READ"] = "identity_provider_read"; PermissionName["IDENTITY_PROVIDER_ROLE_CREATE"] = "identity_provider_role_create"; PermissionName["IDENTITY_PROVIDER_ROLE_DELETE"] = "identity_provider_role_delete"; PermissionName["IDENTITY_PROVIDER_ROLE_UPDATE"] = "identity_provider_role_update"; PermissionName["PERMISSION_CREATE"] = "permission_create"; PermissionName["PERMISSION_DELETE"] = "permission_delete"; PermissionName["PERMISSION_UPDATE"] = "permission_update"; PermissionName["PERMISSION_READ"] = "permission_read"; PermissionName["REALM_CREATE"] = "realm_create"; PermissionName["REALM_DELETE"] = "realm_delete"; PermissionName["REALM_UPDATE"] = "realm_update"; PermissionName["REALM_READ"] = "realm_read"; PermissionName["ROBOT_CREATE"] = "robot_create"; PermissionName["ROBOT_DELETE"] = "robot_delete"; PermissionName["ROBOT_UPDATE"] = "robot_update"; PermissionName["ROBOT_READ"] = "robot_read"; PermissionName["ROBOT_SELF_MANAGE"] = "robot_self_manage"; PermissionName["ROBOT_PERMISSION_CREATE"] = "robot_permission_create"; PermissionName["ROBOT_PERMISSION_DELETE"] = "robot_permission_delete"; PermissionName["ROBOT_PERMISSION_READ"] = "robot_permission_read"; PermissionName["ROBOT_ROLE_CREATE"] = "robot_role_create"; PermissionName["ROBOT_ROLE_DELETE"] = "robot_role_delete"; PermissionName["ROBOT_ROLE_UPDATE"] = "robot_role_update"; PermissionName["ROBOT_ROLE_READ"] = "robot_role_read"; PermissionName["ROLE_CREATE"] = "role_create"; PermissionName["ROLE_DELETE"] = "role_delete"; PermissionName["ROLE_UPDATE"] = "role_update"; PermissionName["ROLE_READ"] = "role_read"; PermissionName["ROLE_PERMISSION_CREATE"] = "role_permission_create"; PermissionName["ROLE_PERMISSION_DELETE"] = "role_permission_delete"; PermissionName["ROLE_PERMISSION_READ"] = "role_permission_read"; PermissionName["SCOPE_CREATE"] = "scope_create"; PermissionName["SCOPE_DELETE"] = "scope_delete"; PermissionName["SCOPE_UPDATE"] = "scope_update"; PermissionName["SCOPE_READ"] = "scope_read"; PermissionName["USER_CREATE"] = "user_create"; PermissionName["USER_DELETE"] = "user_delete"; PermissionName["USER_UPDATE"] = "user_update"; PermissionName["USER_READ"] = "user_read"; PermissionName["USER_SELF_MANAGE"] = "user_self_update"; PermissionName["USER_PERMISSION_CREATE"] = "user_permission_create"; PermissionName["USER_PERMISSION_DELETE"] = "user_permission_delete"; PermissionName["USER_PERMISSION_READ"] = "user_permission_read"; PermissionName["USER_ROLE_CREATE"] = "user_role_create"; PermissionName["USER_ROLE_DELETE"] = "user_role_delete"; PermissionName["USER_ROLE_UPDATE"] = "user_role_update"; PermissionName["USER_ROLE_READ"] = "user_role_read"; return PermissionName; }({}); function isPermissionNameValid(name, options = {}) { return isNameValid(name, options); } class PermissionValidator extends Container { initialize() { super.initialize(); const nameValidator = createValidator(z.string().min(3).max(128).check((ctx)=>{ try { isPermissionNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The permission name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('display_name', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('description', { optional: true }, createValidator(z.string().min(5).max(4096).nullable())); this.mount('client_id', { optional: true }, createValidator(z.uuid())); this.mount('realm_id', { group: ValidatorGroup.CREATE, optional: true }, createValidator(z.uuid().nullable().optional())); this.mount('decision_strategy', { optional: true }, createValidator(z.enum(DecisionStrategy).nullable())); } } /* * Copyright (c) 2025. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function formatKeySegment(value) { if (typeof value === 'undefined') { return '*'; } return value || '_'; } function buildPermissionBindingKey(input) { return `${formatKeySegment(input.realm_id)}/${formatKeySegment(input.client_id)}/${input.name}`; } /* * Copyright (c) 2024-2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function isPermissionBindingEqual(a, b) { if (a.permission.name !== b.permission.name) { return false; } if ((a.permission.realm_id ?? null) !== (b.permission.realm_id ?? null)) { return false; } if ((a.permission.client_id ?? null) !== (b.permission.client_id ?? null)) { return false; } return true; } function mergePermissionBindings(input) { const grouped = input.reduce((previous, current)=>{ const key = buildPermissionBindingKey(current.permission); if (!previous[key]) { previous[key] = []; } previous[key].push(current); return previous; }, {}); const output = []; const keys = Object.keys(grouped); for (const key of keys){ const group = grouped[key]; const first = group[0]; if (group.length === 1) { output.push(first); continue; } const children = []; for (const element of group){ if (!element.policies || element.policies.length === 0) { continue; } const policy = { type: 'composite', decision_strategy: element.permission.decision_strategy || DecisionStrategy.UNANIMOUS, children: element.policies }; children.push(policy); } let mergedPolicies; if (children.length > 0 && children.length === group.length) { const policy = { type: 'composite', decision_strategy: DecisionStrategy.AFFIRMATIVE, children }; mergedPolicies = [ policy ]; } output.push({ permission: { ...first.permission, decision_strategy: DecisionStrategy.AFFIRMATIVE }, policies: mergedPolicies }); } return output; } function isPolicyNameValid(name, options = {}) { return isNameValid(name, options); } class PolicyValidator extends Container { initialize() { super.initialize(); const nameValidator = createValidator(z.string().min(3).max(128).check((ctx)=>{ try { isPolicyNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The policy name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('display_name', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('invert', { optional: true }, createValidator(z.boolean())); this.mount('type', { group: ValidatorGroup.CREATE }, createValidator(z.string().min(3).max(128))); this.mount('parent_id', { optional: true }, createValidator(z.uuid().nullable())); this.mount('realm_id', { group: ValidatorGroup.CREATE, optional: true }, createValidator(z.uuid().nullable())); } } /* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ const REALM_MASTER_NAME = 'master'; const REALM_NAME_REGEX = /^[a-zA-Z0-9_]{3,128}$/; function isRealmNameValid(name, options = {}) { return isNameValid(name, options); } class RealmValidator extends Container { initialize() { super.initialize(); const nameValidator = createValidator(z.string().min(3).max(128).check((ctx)=>{ try { isRealmNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The realm name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('display_name', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('description', { optional: true }, createValidator(z.string().min(5).max(4096).nullable())); } } function isRobotNameValid(name, options = {}) { return isNameValid(name, options); } class RobotError extends AuthupError { static credentialsInvalid() { return new RobotError({ code: ErrorCode.ENTITY_CREDENTIALS_INVALID, message: 'The robot credentials are invalid.' }); } static notFound() { return new RobotError({ code: ErrorCode.ENTITY_NOT_FOUND, message: 'The robot account was not found.' }); } static inactive() { return new RobotError({ code: ErrorCode.ENTITY_INACTIVE, message: 'The robot account is inactive.' }); } } class RobotValidator extends Container { initialize() { super.initialize(); this.mount('secret', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('active', { optional: true }, createValidator(z.boolean())); const nameValidator = createValidator(z.string().min(3).max(128).check((ctx)=>{ try { isRobotNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The robot name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('display_name', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('description', { optional: true }, createValidator(z.string().min(5).max(4096).nullable())); this.mount('user_id', { optional: true }, createValidator(z.uuid())); this.mount('realm_id', { group: ValidatorGroup.CREATE, optional: true }, createValidator(z.uuid())); } } /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ const ROLE_ADMIN_NAME = 'admin'; const ROLE_REALM_ADMIN_NAME = 'realm_admin'; function isRoleNameValid(name, options = {}) { return isNameValid(name, options); } class RoleValidator extends Container { initialize() { super.initialize(); const nameValidator = createValidator(z.string().min(3).max(128).check((ctx)=>{ try { isRoleNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The role name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('display_name', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('description', { optional: true }, createValidator(z.string().min(5).max(4096).nullable())); this.mount('realm_id', { group: ValidatorGroup.CREATE, optional: true }, createValidator(z.uuid().nullable())); } } /* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var ScopeName = /*#__PURE__*/ function(ScopeName) { /** * Full permissions */ ScopeName["GLOBAL"] = "global"; /** * for Openid usage (id-token) */ ScopeName["OPEN_ID"] = "openid"; /** * /users/@me with email (userinfo & id-token) */ ScopeName["EMAIL"] = "email"; /** * Roles array (id-token) */ ScopeName["ROLES"] = "roles"; /** * /users/@me without email (userinfo & id-token) */ ScopeName["IDENTITY"] = "identity"; return ScopeName; }({}); function isScopeNameValid(name, options = {}) { return isNameValid(name, options); } class ScopeValidator extends Container { initialize() { super.initialize(); const nameValidator = createValidator(z.string().min(3).max(128).check((ctx)=>{ try { isScopeNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The scope name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('display_name', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('description', { optional: true }, createValidator(z.string().min(5).max(4096).nullable())); this.mount('realm_id', { group: ValidatorGroup.CREATE, optional: true }, createValidator(z.uuid().nullable())); } } class UserError extends AuthupError { static credentialsInvalid() { return new UserError({ code: ErrorCode.ENTITY_CREDENTIALS_INVALID, message: 'The user credentials are invalid.' }); } static notFound() { return new UserError({ code: ErrorCode.ENTITY_NOT_FOUND, message: 'The user account was not found.' }); } static inactive() { return new UserError({ code: ErrorCode.ENTITY_INACTIVE, message: 'The user account is inactive.' }); } } function isUserNameValid(input, options = {}) { if (!isNameValid(input, options)) return false; input = input.toLowerCase(); const isReservedName = [ 'bot', 'system', 'everyone', 'here' ].some((el)=>input.startsWith(el)); if (isReservedName) { if (options.throwOnFailure) { throw new AuthupError(`${input} is a reserved name.`); } return false; } return true; } function isValidUserEmail(input) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input); } function buildUserFakeEmail(input) { if (isUserFakeEmail(input)) { return input; } return `${input}@example.com`; } function isUserFakeEmail(input) { return input.endsWith('@example.com'); } class UserValidator extends Container { initialize() { super.initialize(); const nameValidator = createValidator(z.string().min(3).max(128).check((ctx)=>{ try { isUserNameValid(ctx.value, { throwOnFailure: true }); } catch (e) { ctx.issues.push({ input: ctx.value, code: 'custom', message: e instanceof Error ? e.message : 'The user name is not valid.' }); } })); this.mount('name', { group: ValidatorGroup.CREATE }, nameValidator); this.mount('name', { group: ValidatorGroup.UPDATE, optional: true }, nameValidator); this.mount('name_locked', { optional: true }, createValidator(z.boolean())); // ---------------------------------------------- this.mount('first_name', { optional: true }, createValidator(z.string().min(3).max(128).nullable())); this.mount('last_name', { optional: true }, createValidator(z.string().min(3).max(128).nullable())); // ---------------------------------------------- this.mount('display_name', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); // ---------------------------------------------- const emailValidator = createValidator(z.email()); this.mount('email', { group: ValidatorGroup.CREATE }, emailValidator); this.mount('email', { optional: true, group: ValidatorGroup.UPDATE }, emailValidator); // ---------------------------------------------- this.mount('password', { optional: true }, createValidator(z.string().min(3).max(512))); // ---------------------------------------------- this.mount('active', { optional: true }, createValidator(z.boolean())); this.mount('name_locked', { optional: true }, createValidator(z.boolean())); this.mount('realm_id', { group: ValidatorGroup.CREATE, optional: true }, createValidator(z.uuid())); this.mount('status', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); this.mount('status_message', { optional: true }, createValidator(z.string().min(3).max(256).nullable())); } } /* * Copyright (c) 2023. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ var EntityType = /*#__PURE__*/ function(EntityType) { EntityType["CLIENT"] = "client"; EntityType["CLIENT_PERMISSION"] = "clientPermission"; EntityType["CLIENT_ROLE"] = "clientRole"; EntityType["CLIENT_SCOPE"] = "clientScope"; EntityType["IDENTITY_PROVIDER"] = "identityProvider"; EntityType["IDENTITY_PROVIDER_ACCOUNT"] = "identityProviderAccount"; EntityType["IDENTITY_PROVIDER_ATTRIBUTE"] = "identityProviderAttribute"; EntityType["IDENTITY_PROVIDER_ATTRIBUTE_MAPPING"] = "identityProviderAttributeMapping"; EntityType["IDENTITY_PROVIDER_PERMISSION_MAPPING"] = "identityProviderPermissionMapping"; EntityType["IDENTITY_PROVIDER_ROLE_MAPPING"] = "identityProviderRoleMapping"; EntityType["KEY"] = "key"; EntityType["POLICY"] = "policy"; EntityType["POLICY_ATTRIBUTE"] = "policyAttribute"; EntityType["PERMISSION"] = "permission"; EntityType["PERMISSION_POLICY"] = "permissionPolicy"; EntityType["REALM"] = "realm"; EntityType["ROBOT"] = "robot"; EntityType["ROBOT_PERMISSION"] = "robotPermission"; EntityType["ROBOT_ROLE"] = "robotRole"; EntityType["ROLE"] = "role"; EntityType["ROLE_ATTRIBUTE"] = "roleAttribute"; EntityType["ROLE_PERMISSION"] = "rolePermission"; EntityType["SCOPE"] = "scope"; EntityType["USER"] = "user"; EntityType["USER_ATTRIBUTE"] = "userAttribute"; EntityType["USER_PERMISSION"] = "userPermission"; EntityType["USER_ROLE"] = "userRole"; return EntityType; }({}); var EntityDefaultEventName = /*#__PURE__*/ function(EntityDefaultEventName) { EntityDefaultEventName["CREATED"] = "created"; EntityDefaultEventName["DELETED"] = "deleted"; EntityDefaultEventName["UPDATED"] = "updated"; return EntityDefaultEventName; }({}); /* * Copyright (c) 2025. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function buildEntityChannelName(entity, id) { return id ? `${entity}:${id}` : entity; } function buildEntityNamespaceName(id) { return `/realm#${id}`; } export { ClientError, ClientValidator, EntityDefaultEventName, EntityType, IdentityProviderAttributesValidator, IdentityProviderLDAPAttributesValidator, IdentityProviderMappingSyncMode, IdentityProviderOAuth2AttributesValidator, IdentityProviderOAuth2PresetAttributesValidator, IdentityProviderPreset, IdentityProviderProtocol, IdentityProviderValidator, IdentityType, PermissionName, PermissionValidator, PolicyValidator, REALM_MASTER_NAME, REALM_NAME_REGEX, ROLE_ADMIN_NAME, ROLE_REALM_ADMIN_NAME, RealmValidator, RobotError, RobotValidator, RoleValidator, ScopeName, ScopeValidator, UserError, UserValidator, ValidatorGroup, buildEntityChannelName, buildEntityNamespaceName, buildIdentityProviderAuthorizeCallbackPath, buildIdentityProviderAuthorizePath, buildPermissionBindingKey, buildUserFakeEmail, getIdentityProviderProtocolForPreset, isClientNameValid, isIdentityProviderNameValid, isLdapIdentityProvider, isNameValid, isOAuth2IdentityProvider, isOpenIDIdentityProvider, isPermissionBindingEqual, isPermissionNameValid, isPolicyNameValid, isRealmNameValid, isRobotNameValid, isRoleNameValid, isScopeNameValid, isUserFakeEmail, isUserNameValid, isValidUserEmail, mergePermissionBindings }; //# sourceMappingURL=index.mjs.map