Files
zooqueenandHanzo Dev ecee5e40aa Sign in through Hanzo IAM only, and make accounts for invited people only
The IAM callback at /auth/callback reads IAM's userinfo answer and refuses
an address IAM has not verified. An account is found by its linked IAM
identity alone (provider hanzo, the IAM subject); an existing account that
only shares the address is refused, never merged. A first sign-in makes an
account only for an admin of the org the application serves or for someone
an organisation invited at that verified address. Every refusal returns to
/signin with a sentence saying what to do.

Accepting an organisation invitation joins the signed-in person, and only
when their verified address is the invited one; opening the link no longer
adds whoever holds the address.

The local email/password sign-up, sign-in, reset, verify-email and update
routes, pages, jobs and mail are gone, as are passkey sign-in, the Google,
Microsoft and generic OIDC providers, the per-organisation SSO portal and
its account-link flow. Passkeys and two-factor stay for confirming a
signature. The e2e suite starts sessions the way a finished IAM sign-in
leaves them.

Co-authored-by: Hanzo Dev <[email protected]>
2026-10-16 01:52:24 -07:00

131 lines
3.1 KiB
TypeScript

import { OrganisationGroupType, OrganisationMemberRole } from '@prisma/client';
export const ORGANISATION_URL_ROOT_REGEX = new RegExp('^/t/[^/]+/?$');
export const ORGANISATION_URL_REGEX = new RegExp('^/t/[^/]+');
export const ORGANISATION_INTERNAL_GROUPS: {
organisationRole: OrganisationMemberRole;
type: OrganisationGroupType;
}[] = [
{
organisationRole: OrganisationMemberRole.ADMIN,
type: OrganisationGroupType.INTERNAL_ORGANISATION,
},
{
organisationRole: OrganisationMemberRole.MANAGER,
type: OrganisationGroupType.INTERNAL_ORGANISATION,
},
{
organisationRole: OrganisationMemberRole.MEMBER,
type: OrganisationGroupType.INTERNAL_ORGANISATION,
},
] as const;
export const ORGANISATION_MEMBER_ROLE_PERMISSIONS_MAP = {
/**
* Includes permissions to:
* - Manage organisation members
* - Manage organisation settings, changing name, url, etc.
*/
DELETE_ORGANISATION: [OrganisationMemberRole.ADMIN],
MANAGE_BILLING: [OrganisationMemberRole.ADMIN],
DELETE_ORGANISATION_TRANSFER_REQUEST: [OrganisationMemberRole.ADMIN],
MANAGE_ORGANISATION: [OrganisationMemberRole.ADMIN, OrganisationMemberRole.MANAGER],
} satisfies Record<string, OrganisationMemberRole[]>;
/**
* A hierarchy of organisation member roles to determine which role has higher permission than another.
*
* Warning: The length of the array is used to determine the priority of the role.
* See `getHighestOrganisationRoleInGroup`
*/
export const ORGANISATION_MEMBER_ROLE_HIERARCHY = {
[OrganisationMemberRole.ADMIN]: [
OrganisationMemberRole.ADMIN,
OrganisationMemberRole.MANAGER,
OrganisationMemberRole.MEMBER,
],
[OrganisationMemberRole.MANAGER]: [OrganisationMemberRole.MANAGER, OrganisationMemberRole.MEMBER],
[OrganisationMemberRole.MEMBER]: [OrganisationMemberRole.MEMBER],
} satisfies Record<OrganisationMemberRole, OrganisationMemberRole[]>;
export const LOWEST_ORGANISATION_ROLE = OrganisationMemberRole.MEMBER;
export const PROTECTED_ORGANISATION_URLS = [
'403',
'404',
'500',
'502',
'503',
'504',
'about',
'account',
'admin',
'administrator',
'api',
'app',
'archive',
'auth',
'backup',
'config',
'configure',
'contact',
'contact-us',
'copyright',
'crime',
'criminal',
'dashboard',
'docs',
'documentation',
'document',
'documents',
'error',
'exploit',
'exploitation',
'exploiter',
'feedback',
'finance',
'forgot-password',
'fraud',
'fraudulent',
'hack',
'hacker',
'harassment',
'help',
'helpdesk',
'illegal',
'internal',
'legal',
'login',
'logout',
'maintenance',
'malware',
'newsletter',
'policy',
'privacy',
'profile',
'public',
'reset-password',
'scam',
'scammer',
'settings',
'setup',
'sign',
'signin',
'signout',
'signup',
'spam',
'support',
'system',
'organisation',
'terms',
'virus',
'webhook',
];
export const isOrganisationUrlProtected = (url: string) => {
return PROTECTED_ORGANISATION_URLS.some((protectedUrl) => url.startsWith(`/${protectedUrl}`));
};
export const ORGANISATION_USER_ACCOUNT_TYPE = 'org-oidc';