import { MastoApiError } from "./catch-errors.js";
import { OAuthTokens } from "../../../../models/index.js";
import authenticate from "../../authenticate.js";
import { AuthHelpers } from "../helpers/auth.js";
export async function AuthMiddleware(ctx, next) {
    const token = await getTokenFromOAuth(ctx.headers.authorization);
    ctx.appId = token?.appId;
    ctx.user = token?.user ?? null;
    ctx.scopes = token?.scopes ?? [];
    await next();
}
export async function getTokenFromOAuth(authorization) {
    if (authorization == null) return null;
    if (authorization.substring(0, 7).toLowerCase() === "bearer ") authorization = authorization.substring(7);
    return OAuthTokens.findOne({
        where: {
            token: authorization,
            active: true
        },
        relations: [
            'user'
        ]
    }).then((token)=>{
        if (!token) return null;
        return {
            ...token,
            scopes: AuthHelpers.expandScopes(token.scopes)
        };
    });
}
export function auth(required, scopes = []) {
    return async function auth(ctx, next) {
        if (required && !ctx.user) throw new MastoApiError(401, "This method requires an authenticated user");
        if (!scopes.every((p)=>ctx.scopes.includes(p))) {
            if (required) throw new MastoApiError(403, "This action is outside the authorized scopes");
            ctx.user = null;
            ctx.scopes = [];
        }
        await next();
    };
}
export function MiAuth(required) {
    return async function MiAuth(ctx, next) {
        ctx.miauth = await authenticate(ctx.headers.authorization, null, true).catch((_)=>[
                null,
                null
            ]);
        if (required && !ctx.miauth[0]) throw new MastoApiError(401, "Unauthorized");
        await next();
    };
}
