Files
zooqueenandHanzo Dev 1fa3aaa4a4 Honour only what IAM-only sign-in issued, and let only ADMINs bring people in
A returning person is found by their linked IAM identity and let in unless
disabled, before anything else is asked; IAM has already authenticated
them. A verified address is required only to make an account. Each sign-in
restates IAM's answer on the account: whether its address is verified, and
ADMIN exactly when IAM says the person administers the app's org.

IAM_ONLY_SINCE is this commit's instant. Sessions, API tokens and
invitations created before it were issued under the old sign-in rules: the
sessions and tokens are refused, and the invitations make no account. A
session also needs a user who is not disabled and is linked to an IAM
identity, and it lives 30 days from the sign-in that made it, never
extended. An API token held by a disabled user is refused.

Creating an organisation, inviting and resending an invitation require
ADMIN. An invitation records its sender (OrganisationMemberInvite.inviterId,
migration 1_organisation_member_invite_inviter), and makes an account only
while that sender holds ADMIN and is not disabled. The reset-token reader
left from the removed password flow goes too.

The decisions are pure functions with their own tests; the e2e fixture
links its users to an IAM identity, as a session now requires.

Co-authored-by: Hanzo Dev <[email protected]>
2026-10-16 09:51:53 +00:00

29 lines
846 B
TypeScript

import { prisma } from '@hanzo/esign-prisma';
import { AppError, AppErrorCode } from '../../errors/app-error';
import { isAdmin } from '../../utils/is-admin';
/**
* Refuses unless the user holds ADMIN and is not disabled. ADMIN is what an IAM
* sign-in grants a person IAM says administers the app's org, so this is the
* gate on bringing anyone new in: creating an organisation and inviting people.
*/
export const assertAdmin = async (userId: number): Promise<void> => {
const user = await prisma.user.findFirst({
where: {
id: userId,
},
select: {
roles: true,
disabled: true,
},
});
if (!user || user.disabled || !isAdmin(user)) {
throw new AppError(AppErrorCode.UNAUTHORIZED, {
message: 'Only an admin can create organisations and invite people',
statusCode: 403,
});
}
};