Document Directus production contract and repair auth
This commit is contained in:
parent
0a7ee5ff35
commit
92ce8bce97
32 changed files with 24821 additions and 65 deletions
|
|
@ -4,14 +4,28 @@
|
|||
// ⚠️ NOTE: Do NOT import `headers()` / `cookies()` from "next/headers" here.
|
||||
// Next 15's types can make those async and break build-time type checks in shared libs.
|
||||
|
||||
const BASE = (process.env.DIRECTUS_URL || "").replace(/\/$/, "");
|
||||
const TOKEN_ADMIN_REGISTER = process.env.DIRECTUS_TOKEN_ADMIN_REGISTER || ""; // server-only
|
||||
const BASE = (
|
||||
process.env.DIRECTUS_URL ||
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ||
|
||||
""
|
||||
).replace(/\/$/, "");
|
||||
// DIRECTUS_TOKEN_ADMIN_REGISTER is the canonical credential for the production
|
||||
// Registration Bot policy. Keep the older aliases as fallbacks so an existing
|
||||
// deployment does not silently lose authentication during migration.
|
||||
const TOKEN_ADMIN_REGISTER =
|
||||
process.env.DIRECTUS_TOKEN_ADMIN_REGISTER ||
|
||||
process.env.DIRECTUS_SERVICE_TOKEN ||
|
||||
process.env.DIRECTUS_ADMIN_TOKEN ||
|
||||
""; // server-only
|
||||
const ROLE_MEMBER_NAME = process.env.DIRECTUS_ROLE_MEMBER_NAME || "Users";
|
||||
const PROJECTS_COLLECTION = process.env.DIRECTUS_PROJECTS_COLLECTION || "projects";
|
||||
|
||||
if (!BASE) console.warn("[directus] Missing DIRECTUS_URL");
|
||||
if (!BASE) console.warn("[directus] Missing DIRECTUS_URL / NEXT_PUBLIC_API_BASE_URL");
|
||||
if (!TOKEN_ADMIN_REGISTER)
|
||||
console.warn("[directus] Missing DIRECTUS_TOKEN_ADMIN_REGISTER (used for registration and username login)");
|
||||
console.warn(
|
||||
"[directus] Missing DIRECTUS_TOKEN_ADMIN_REGISTER (or legacy service-token alias) " +
|
||||
"used for registration and username login"
|
||||
);
|
||||
|
||||
export function bytesFromMB(mb: number) {
|
||||
return Math.round(mb * 1024 * 1024);
|
||||
|
|
@ -119,7 +133,8 @@ export async function dxDELETE<T = any>(path: string, bearer: string): Promise<T
|
|||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
export async function directusAdminFetch<T = any>(path: string, init?: RequestInit): Promise<T> {
|
||||
if (!TOKEN_ADMIN_REGISTER) throw new Error("Missing DIRECTUS_TOKEN_ADMIN_REGISTER");
|
||||
if (!BASE) throw new Error("Missing Directus base URL");
|
||||
if (!TOKEN_ADMIN_REGISTER) throw new Error("Missing Directus registration credential");
|
||||
const res = await fetch(`${BASE}${path}`, {
|
||||
...init,
|
||||
headers: {
|
||||
|
|
@ -231,13 +246,25 @@ export async function createDirectusUser(input: {
|
|||
}
|
||||
|
||||
export async function emailForUsername(username: string): Promise<string | null> {
|
||||
const q = `/users?filter[username][_eq]=${encodeURIComponent(username)}&fields=email&limit=1`;
|
||||
const clean = username.trim();
|
||||
if (!clean) return null;
|
||||
const q = `/users?filter[username][_eq]=${encodeURIComponent(clean)}&fields=email&limit=1`;
|
||||
const { data } = await directusAdminFetch<{ data: Array<{ email?: string }> }>(q);
|
||||
const em = data?.[0]?.email;
|
||||
return em ? String(em) : null;
|
||||
}
|
||||
|
||||
export async function directusUserExists(email: string, username: string): Promise<boolean> {
|
||||
const q =
|
||||
`/users?filter[_or][0][email][_eq]=${encodeURIComponent(email)}` +
|
||||
`&filter[_or][1][username][_eq]=${encodeURIComponent(username)}` +
|
||||
`&fields=id&limit=1`;
|
||||
const { data } = await directusAdminFetch<{ data: Array<{ id: string }> }>(q);
|
||||
return Array.isArray(data) && data.length > 0;
|
||||
}
|
||||
|
||||
export async function loginDirectus(email: string, password: string) {
|
||||
if (!BASE) throw new Error("Missing Directus base URL");
|
||||
const res = await fetch(`${BASE}/auth/login`, {
|
||||
method: "POST",
|
||||
headers: { Accept: "application/json", "Content-Type": "application/json" },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue