uth(register): force “Users” role at signup; remove DIRECTUS_ROLE_MEMBER_ID override and disallow caller-provided roles

This commit is contained in:
makearmy 2025-09-29 14:43:42 -04:00
parent 096da254ec
commit 63ddd29393

View file

@ -3,8 +3,7 @@
const BASE = (process.env.DIRECTUS_URL || "").replace(/\/$/, ""); const BASE = (process.env.DIRECTUS_URL || "").replace(/\/$/, "");
const TOKEN_ADMIN_REGISTER = process.env.DIRECTUS_TOKEN_ADMIN_REGISTER || ""; // server-only const TOKEN_ADMIN_REGISTER = process.env.DIRECTUS_TOKEN_ADMIN_REGISTER || ""; // server-only
const ROLE_MEMBER_ID_ENV = process.env.DIRECTUS_ROLE_MEMBER_ID || ""; const ROLE_MEMBER_NAME = process.env.DIRECTUS_ROLE_MEMBER_NAME || "Users";
const ROLE_MEMBER_NAME_ENV = process.env.DIRECTUS_ROLE_MEMBER_NAME || "Users";
const PROJECTS_COLLECTION = process.env.DIRECTUS_PROJECTS_COLLECTION || "projects"; const PROJECTS_COLLECTION = process.env.DIRECTUS_PROJECTS_COLLECTION || "projects";
@ -209,9 +208,7 @@ export async function patchProject(
// ───────────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────────
export async function resolveMemberRoleId(): Promise<string> { export async function resolveMemberRoleId(): Promise<string> {
if (ROLE_MEMBER_ID_ENV) return ROLE_MEMBER_ID_ENV; const name = ROLE_MEMBER_NAME;
const name = ROLE_MEMBER_NAME_ENV;
const q = `/roles?filter[name][_eq]=${encodeURIComponent(name)}&fields=id,name&limit=1`; const q = `/roles?filter[name][_eq]=${encodeURIComponent(name)}&fields=id,name&limit=1`;
const { data } = await directusAdminFetch<{ data: Array<{ id: string }> }>(q); const { data } = await directusAdminFetch<{ data: Array<{ id: string }> }>(q);
const hit = data?.[0]?.id; const hit = data?.[0]?.id;
@ -219,14 +216,15 @@ export async function resolveMemberRoleId(): Promise<string> {
return hit; return hit;
} }
/** Registrations always create a 'Users' role account. No overrides. */
export async function createDirectusUser(input: { export async function createDirectusUser(input: {
username: string; username: string;
password: string; password: string;
email?: string; email?: string;
roleId?: string;
}): Promise<{ id: string }> { }): Promise<{ id: string }> {
const role = input.roleId || (await resolveMemberRoleId()); const role = await resolveMemberRoleId();
// If email is omitted, create a stable placeholder so login can still work.
const email = const email =
input.email && input.email.trim() input.email && input.email.trim()
? input.email.trim() ? input.email.trim()
@ -262,5 +260,6 @@ export async function loginDirectus(email: string, password: string) {
cache: "no-store", cache: "no-store",
}); });
const json = await throwIfNotOk(res); const json = await throwIfNotOk(res);
// Directus typically returns { data: { access_token, refresh_token, expires } }
return json?.data ?? json; return json?.data ?? json;
} }