mirror of
https://github.com/mollersuite/monofile.git
synced 2024-11-25 15:06:26 -08:00
barebones invite api
This commit is contained in:
parent
1703320b84
commit
426e057f12
35
src/server/lib/invites.ts
Normal file
35
src/server/lib/invites.ts
Normal 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()
|
|
@ -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"))
|
||||||
|
|
|
@ -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"
|
||||||
|
|
40
src/server/routes/api/v1/server/invites.ts
Normal file
40
src/server/routes/api/v1/server/invites.ts
Normal 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
|
||||||
|
}
|
Loading…
Reference in a new issue