barebones invite api

This commit is contained in:
May 2024-06-17 16:43:19 -07:00
parent 1703320b84
commit 426e057f12
4 changed files with 92 additions and 4 deletions

35
src/server/lib/invites.ts Normal file
View file

@ -0,0 +1,35 @@
// The only reason we have this is to make
// life very, very slightly easier.
// And also we can change how the invite
// system works a little easily
// if need be, I guess?
import DbFile from "./dbfile.js";
import { generateFileId } from "./files.js";
export const Db = new DbFile<string[]>("invites", [])
export function has(id: string) {
return Db.data.includes(id)
}
export function use(id: string) {
if (!has(id)) return false
Db.data.splice(
Db.data.indexOf(id),
1
)
Db.save()
return true
}
export function make() {
let invite = generateFileId(6)
Db.data.push(invite)
Db.save()
return invite
}
Db.read()

View file

@ -28,6 +28,7 @@ import * as CodeMgr from "../../../../lib/codes.js"
import Configuration from "../../../../lib/config.js" import Configuration from "../../../../lib/config.js"
import { AccountSchemas, FileSchemas } from "../../../../lib/schemas/index.js" import { AccountSchemas, FileSchemas } from "../../../../lib/schemas/index.js"
import { z } from "zod" import { z } from "zod"
import * as invites from "../../../../lib/invites.js"
const router = new Hono<{ const router = new Hono<{
Variables: { Variables: {
@ -260,12 +261,17 @@ const UserUpdateScheme = z.union([
export default function (files: Files) { export default function (files: Files) {
router.post("/", scheme(z.object({ router.post("/", scheme(z.object({
username: AccountSchemas.Username, username: AccountSchemas.Username,
password: AccountSchemas.StringPassword password: AccountSchemas.StringPassword,
})), async (ctx) => { invite: z.string().max(6)
}).omit(
Configuration.accounts.requiredForUpload
? { invite: true }
: {}
)), async (ctx) => {
const body = await ctx.req.json() const body = await ctx.req.json()
if (!ctx.get("account")?.admin) { if (!ctx.get("account")?.admin) {
if (!Configuration.accounts.registrationEnabled) if (body.invite && !invites.has(body.invite))
return ServeError(ctx, 403, "account registration disabled") return ServeError(ctx, 400, "invite invalid")
if (ctx.get("account")) if (ctx.get("account"))
return ServeError(ctx, 400, "you are already logged in") return ServeError(ctx, 400, "you are already logged in")
@ -279,6 +285,9 @@ export default function (files: Files) {
) )
} }
if (body.invite)
invites.use(body.invite)
return Accounts.create(body.username, body.password) return Accounts.create(body.username, body.password)
.then((account) => { .then((account) => {
if (!ctx.get("account")) if (!ctx.get("account"))

View file

@ -29,6 +29,10 @@ export default {
"file": "file/individual", "file": "file/individual",
"to": "/file" "to": "/file"
}, },
{
"file": "/server/invites",
"to": "/server/invites"
},
{ {
"file": "/server/run", "file": "/server/run",
"to": "/server/run" "to": "/server/run"

View file

@ -0,0 +1,40 @@
import { Hono } from "hono"
import * as Accounts from "../../../../lib/accounts.js"
import * as auth from "../../../../lib/auth.js"
import { HttpBindings } from "@hono/node-server"
import config, { ClientConfiguration } from "../../../../lib/config.js"
import type Files from "../../../../lib/files.js"
import { getAccount, requiresAccount, requiresAdmin } from "../../../../lib/middleware.js"
import { Writable } from "node:stream"
import { Db, make, use } from "../../../../lib/invites.js"
import ServeError from "../../../../lib/errors.js"
const router = new Hono<{
Variables: {
account: Accounts.Account
},
Bindings: HttpBindings
}>()
router.use(getAccount, requiresAccount, requiresAdmin)
export default function(files: Files) {
// api is structured like this
// in case invites become more complicated
// in the future
// if and when the api does become more complex
// i'll probably add GET /server/invites/:invite etc
router.post("/", async (ctx) => ctx.json({id: make()}))
router.get("/", async (ctx) => ctx.json(Db.data.map(e => ({id: e}))))
router.delete("/:invite", async (ctx) => {
if (use(ctx.req.param("invite"))) {
return ctx.json({id: ctx.req.param("invite")})
} else {
return ServeError(ctx, 404, "invalid invite")
}
})
return router
}