partial: new documentation additions (company admin)

This commit is contained in:
DecDuck
2025-08-09 22:18:34 +10:00
parent 7af29ef0eb
commit ef7a62bf0b
15 changed files with 181 additions and 122 deletions

View File

@ -2,6 +2,9 @@ import { AuthMec } from "~/prisma/client/enums";
import aclManager from "~/server/internal/acls";
import authManager from "~/server/internal/auth";
/**
* Fetches all the enabled authentication mechanisms on this instance, and their configuration, if enabled.
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["auth:read", "setup"]);
if (!allowed) throw createError({ statusCode: 403 });

View File

@ -8,7 +8,8 @@ const DeleteInvite = type({
}).configure(throwingArktype);
/**
* Delete a simple auth invitation
* Deletes a "Simple" invitation
* @returns nothing
*/
export default defineEventHandler<{
body: typeof DeleteInvite.infer;

View File

@ -3,6 +3,9 @@ import { systemConfig } from "~/server/internal/config/sys-conf";
import prisma from "~/server/internal/db/database";
import taskHandler from "~/server/internal/tasks";
/**
* Fetches a "Simple" invitation
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, [
"auth:simple:invitation:read",

View File

@ -11,6 +11,9 @@ const CreateInvite = SharedRegisterValidator.partial()
})
.configure(throwingArktype);
/**
* Creates a "Simple" invitation
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, [
"auth:simple:invitation:new",

View File

@ -3,6 +3,11 @@ import prisma from "~/server/internal/db/database";
import objectHandler from "~/server/internal/objects";
import { handleFileUpload } from "~/server/internal/utils/handlefileupload";
/**
* Multi-part form upload for the banner.
* @request `multipart/form-data` data. Only one file, can be named anything.
* @param id Company ID
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });

View File

@ -7,31 +7,37 @@ const GameDelete = type({
id: "string",
}).configure(throwingArktype);
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });
/**
* Delete a game's association with a company
* @param id Company ID
*/
export default defineEventHandler<{ body: typeof GameDelete.infer }>(
async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });
const companyId = getRouterParam(h3, "id")!;
const companyId = getRouterParam(h3, "id")!;
const body = await readDropValidatedBody(h3, GameDelete);
const body = await readDropValidatedBody(h3, GameDelete);
await prisma.game.update({
where: {
id: body.id,
},
data: {
publishers: {
disconnect: {
id: companyId,
await prisma.game.update({
where: {
id: body.id,
},
data: {
publishers: {
disconnect: {
id: companyId,
},
},
developers: {
disconnect: {
id: companyId,
},
},
},
developers: {
disconnect: {
id: companyId,
},
},
},
});
});
return;
});
return;
},
);

View File

@ -9,29 +9,35 @@ const GamePatch = type({
id: "string",
}).configure(throwingArktype);
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });
/**
* Update a company's association with a game.
* @param id Company ID
*/
export default defineEventHandler<{ body: typeof GamePatch.infer }>(
async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });
const companyId = getRouterParam(h3, "id")!;
const companyId = getRouterParam(h3, "id")!;
const body = await readDropValidatedBody(h3, GamePatch);
const body = await readDropValidatedBody(h3, GamePatch);
const action = body.action === "developed" ? "developers" : "publishers";
const actionType = body.enabled ? "connect" : "disconnect";
const action = body.action === "developed" ? "developers" : "publishers";
const actionType = body.enabled ? "connect" : "disconnect";
await prisma.game.update({
where: {
id: body.id,
},
data: {
[action]: {
[actionType]: {
id: companyId,
await prisma.game.update({
where: {
id: body.id,
},
data: {
[action]: {
[actionType]: {
id: companyId,
},
},
},
},
});
});
return;
});
return;
},
);

View File

@ -9,61 +9,67 @@ const GamePost = type({
id: "string",
}).configure(throwingArktype);
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });
/**
* Add a new game association to this company
* @param id Company ID
*/
export default defineEventHandler<{ body: typeof GamePost.infer }>(
async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });
const companyId = getRouterParam(h3, "id")!;
const companyId = getRouterParam(h3, "id")!;
const body = await readDropValidatedBody(h3, GamePost);
const body = await readDropValidatedBody(h3, GamePost);
if (!body.published && !body.developed)
throw createError({
statusCode: 400,
statusMessage: "Must be related (either developed or published).",
if (!body.published && !body.developed)
throw createError({
statusCode: 400,
statusMessage: "Must be related (either developed or published).",
});
const publisherConnect = body.published
? {
publishers: {
connect: {
id: companyId,
},
},
}
: undefined;
const developerConnect = body.developed
? {
developers: {
connect: {
id: companyId,
},
},
}
: undefined;
const game = await prisma.game.update({
where: {
id: body.id,
},
data: {
...publisherConnect,
...developerConnect,
},
include: {
publishers: {
select: {
id: true,
},
},
developers: {
select: {
id: true,
},
},
},
});
const publisherConnect = body.published
? {
publishers: {
connect: {
id: companyId,
},
},
}
: undefined;
const developerConnect = body.developed
? {
developers: {
connect: {
id: companyId,
},
},
}
: undefined;
const game = await prisma.game.update({
where: {
id: body.id,
},
data: {
...publisherConnect,
...developerConnect,
},
include: {
publishers: {
select: {
id: true,
},
},
developers: {
select: {
id: true,
},
},
},
});
return game;
});
return game;
},
);

View File

@ -3,6 +3,11 @@ import prisma from "~/server/internal/db/database";
import objectHandler from "~/server/internal/objects";
import { handleFileUpload } from "~/server/internal/utils/handlefileupload";
/**
* Multi-part form upload for the icon of this company
* @request `multipart/form-data` data. Only one file, can be named anything.
* @param id Company ID
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });

View File

@ -1,6 +1,10 @@
import aclManager from "~/server/internal/acls";
import prisma from "~/server/internal/db/database";
/**
* Delete this company
* @param id Company ID
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:delete"]);
if (!allowed) throw createError({ statusCode: 403 });

View File

@ -1,6 +1,10 @@
import aclManager from "~/server/internal/acls";
import prisma from "~/server/internal/db/database";
/**
* Fetch a company and its associations
* @param id Company ID
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:read"]);
if (!allowed) throw createError({ statusCode: 403 });

View File

@ -1,6 +1,11 @@
import aclManager from "~/server/internal/acls";
import prisma from "~/server/internal/db/database";
/**
* Update a company. Pass any fields into the body to be updated on the model
* @request Partial of the data returned by GET, minus the `developed` and `published` fields.
* @param id Company ID
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:update"]);
if (!allowed) throw createError({ statusCode: 403 });

View File

@ -1,6 +1,9 @@
import aclManager from "~/server/internal/acls";
import prisma from "~/server/internal/db/database";
/**
* Fetch all companies on this instance
*/
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:read"]);
if (!allowed) throw createError({ statusCode: 403 });

View File

@ -12,36 +12,41 @@ const CompanyCreate = type({
website: "string",
}).configure(throwingArktype);
export default defineEventHandler(async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:create"]);
if (!allowed) throw createError({ statusCode: 403 });
/**
* Create a new company on this instance
*/
export default defineEventHandler<{ body: typeof CompanyCreate.infer }>(
async (h3) => {
const allowed = await aclManager.allowSystemACL(h3, ["company:create"]);
if (!allowed) throw createError({ statusCode: 403 });
const body = await readDropValidatedBody(h3, CompanyCreate);
const obj = new ObjectTransactionalHandler();
const [register, pull, _] = obj.new({}, ["internal:read"]);
const body = await readDropValidatedBody(h3, CompanyCreate);
const obj = new ObjectTransactionalHandler();
const [register, pull, _] = obj.new({}, ["internal:read"]);
const icon = jdenticon.toPng(body.name, 512);
const logoId = register(icon);
const icon = jdenticon.toPng(body.name, 512);
const logoId = register(icon);
const banner = jdenticon.toPng(body.description, 1024);
const bannerId = register(banner);
const banner = jdenticon.toPng(body.description, 1024);
const bannerId = register(banner);
const company = await prisma.company.create({
data: {
metadataSource: MetadataSource.Manual,
metadataId: crypto.randomUUID(),
metadataOriginalQuery: "",
const company = await prisma.company.create({
data: {
metadataSource: MetadataSource.Manual,
metadataId: crypto.randomUUID(),
metadataOriginalQuery: "",
mName: body.name,
mShortDescription: body.description,
mDescription: "",
mLogoObjectId: logoId,
mBannerObjectId: bannerId,
mWebsite: body.website,
},
});
mName: body.name,
mShortDescription: body.description,
mDescription: "",
mLogoObjectId: logoId,
mBannerObjectId: bannerId,
mWebsite: body.website,
},
});
await pull();
await pull();
return company;
});
return company;
},
);

View File

@ -1,6 +1,6 @@
import { systemConfig } from "~/server/internal/config/sys-conf";
export default defineEventHandler((_h3) => {
export default defineEventHandler(async (_h3) => {
return {
appName: "Drop",
version: systemConfig.getDropVersion(),