fix a few implementations

This commit is contained in:
May 2024-05-24 21:17:05 -07:00
parent 2f32644b3d
commit b130e4e2cb
6 changed files with 38 additions and 36 deletions

View file

@ -21,12 +21,9 @@ export type Account = z.infer<typeof AccountSchemas.Account>
* @returns A Promise which returns the new account's ID * @returns A Promise which returns the new account's ID
*/ */
export async function create(username:string,pwd:string,admin:boolean=false):Promise<string> { export async function create(username:string,pwd:string,admin:boolean=false):Promise<Account> {
let accId = crypto.randomBytes(12).toString("hex") let acc: Account = {
id: crypto.randomUUID(),
Db.data.push(
{
id: accId,
username: username, username: username,
password: password.hash(pwd), password: password.hash(pwd),
files: [], files: [],
@ -34,10 +31,11 @@ export async function create(username:string,pwd:string,admin:boolean=false):Pro
defaultFileVisibility: "public", defaultFileVisibility: "public",
settings: AccountSchemas.Settings.User.parse({}) settings: AccountSchemas.Settings.User.parse({})
} }
)
Db.data.push(acc)
await Db.save() await Db.save()
return accId
return acc
} }
/** /**

View file

@ -59,7 +59,7 @@ export function makeJwt(_token: TokenResolvable) {
sub: token.account, sub: token.account,
jti: token.id, jti: token.id,
...(token.type != "User" ? { scope: token.scopes } : {}) ...(token.type != "User" ? { scope: token.scopes } : {})
}) }).setProtectedHeader({ alg: "HS256" })
return jwt.sign(config.jwtSecret) return jwt.sign(config.jwtSecret)
} }

View file

@ -10,19 +10,18 @@ import { codes } from "./codes.js"
* @description Middleware which adds an account, if any, to ctx.get("account") * @description Middleware which adds an account, if any, to ctx.get("account")
*/ */
export const getAccount: RequestHandler = async function (ctx, next) { export const getAccount: RequestHandler = async function (ctx, next) {
let account = Accounts.getFromToken((await auth.tokenFor(ctx))!) let uToken = (await auth.tokenFor(ctx))!
let account = Accounts.getFromToken(uToken)
if (account?.suspension) if (account?.suspension)
setCookie(ctx, "auth", "") auth.invalidate(uToken)
ctx.set("account", account) ctx.set("account", account)
return next() return next()
} }
export function resolveTarget(actor: Accounts.Account, targetString: string) { export function resolveTarget(actor: Accounts.Account, target: Accounts.AccountResolvable) {
return targetString == "me" return target == "me"
? actor ? actor
: targetString.startsWith("@") : Accounts.resolve(target)
? Accounts.getFromUsername(targetString.slice(1))
: Accounts.getFromId(targetString)
} }
/** /**
@ -36,7 +35,6 @@ export const getTarget: RequestHandler = async (ctx, next) => {
permissions = auth.getScopes(tok) permissions = auth.getScopes(tok)
let actor = ctx.get("account") let actor = ctx.get("account")
let target = resolveTarget(actor, ctx.req.param("user")) let target = resolveTarget(actor, ctx.req.param("user"))
if (!target) return ServeError(ctx, 404, "account does not exist") if (!target) return ServeError(ctx, 404, "account does not exist")
@ -44,11 +42,12 @@ export const getTarget: RequestHandler = async (ctx, next) => {
if (actor && ( if (actor && (
( (
target != actor // target is not the current account target != actor // target is not the current account
&& !actor?.admin // account is not admin && (
) !actor?.admin // account is not admin
|| ( || (
actor?.admin // account is admin permissions && !permissions.includes("manage_server") // account is admin but permissions does not include manage_server
&& permissions && !permissions.includes("manage_server") // permissions does not include manage_server )
)
) )
)) ))
return ServeError(ctx, 403, "you cannot manage this user") return ServeError(ctx, 403, "you cannot manage this user")
@ -188,7 +187,7 @@ export function scheme(scheme: z.ZodTypeAny, transformer: (ctx: Context) => Prom
// Not really middleware but a utility // Not really middleware but a utility
export const login = async (ctx: Context, account: string) => { export const login = async (ctx: Context, account: Accounts.AccountResolvable) => {
let token = auth.create(account, 3 * 24 * 60 * 60 * 1000) let token = auth.create(account, 3 * 24 * 60 * 60 * 1000)
setCookie(ctx, "auth", await auth.makeJwt(token), { setCookie(ctx, "auth", await auth.makeJwt(token), {
path: "/", path: "/",

View file

@ -90,7 +90,7 @@ export default function (files: Files) {
}) })
router.delete("/:token", async (ctx) => { router.delete("/:token", async (ctx) => {
auth.invalidate(ctx.get("targetToken").id) auth.invalidate(ctx.get("targetToken"))
return ctx.text(`deleted token ${ctx.req.param("token")}`) return ctx.text(`deleted token ${ctx.req.param("token")}`)
}) })

View file

@ -217,7 +217,12 @@ router.use(getAccount)
router.on( router.on(
["GET","PATCH","DELETE"], ["GET","PATCH","DELETE"],
"/:user", "/:user",
requiresAccount, getTarget, accountMgmtRoute requiresAccount, getTarget
)
router.on(
["PATCH","DELETE"],
"/:user",
accountMgmtRoute
) )
function isMessage(object: any): object is Message { function isMessage(object: any): object is Message {
@ -278,7 +283,7 @@ export default function (files: Files) {
.then((account) => { .then((account) => {
if (!ctx.get("account")) if (!ctx.get("account"))
login(ctx, account) login(ctx, account)
return ctx.text(account) return ctx.text(account.id)
}) })
.catch((e) => { .catch((e) => {
console.error(e) console.error(e)

View file

@ -12,6 +12,7 @@ import * as auth from "../../../lib/auth.js"
import { import {
getAccount, getAccount,
login, login,
mirror,
requiresAccount, requiresAccount,
scheme scheme
} from "../../../lib/middleware.js" } from "../../../lib/middleware.js"
@ -27,7 +28,7 @@ const router = new Hono<{
router.use(getAccount) router.use(getAccount)
export default function (files: Files) { export default function (files: Files, apiRoot: Hono) {
router.post("/",scheme(z.object({ router.post("/",scheme(z.object({
username: AccountSchemas.Username, username: AccountSchemas.Username,
password: AccountSchemas.StringPassword password: AccountSchemas.StringPassword
@ -59,8 +60,7 @@ export default function (files: Files) {
}) })
router.get("/", requiresAccount, async ctx => { router.get("/", requiresAccount, async ctx => {
let sessionToken = (await auth.tokenFor(ctx))! return ctx.json(auth.resolve((await auth.tokenFor(ctx))!)!)
return ctx.redirect(`/api/v1`)
}) })
router.delete("/", requiresAccount, async ctx => { router.delete("/", requiresAccount, async ctx => {