mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-14 00:31:25 +10:00
feat: add cloud save backend
This commit is contained in:
@ -4,7 +4,6 @@ import { useCertificateAuthority } from "~/server/plugins/ca";
|
||||
import prisma from "../db/database";
|
||||
import { ClientCapabilities } from "@prisma/client";
|
||||
|
||||
|
||||
// These values are technically mapped to the database,
|
||||
// but Typescript/Prisma doesn't let me link them
|
||||
// They are also what are required by clients in the API
|
||||
@ -12,6 +11,7 @@ import { ClientCapabilities } from "@prisma/client";
|
||||
export enum InternalClientCapability {
|
||||
PeerAPI = "peerAPI",
|
||||
UserStatus = "userStatus",
|
||||
CloudSaves = "cloudSaves",
|
||||
}
|
||||
|
||||
export const validCapabilities = Object.values(InternalClientCapability);
|
||||
@ -19,6 +19,7 @@ export const validCapabilities = Object.values(InternalClientCapability);
|
||||
export type CapabilityConfiguration = {
|
||||
[InternalClientCapability.PeerAPI]: { endpoints: string[] };
|
||||
[InternalClientCapability.UserStatus]: {};
|
||||
[InternalClientCapability.CloudSaves]: {};
|
||||
};
|
||||
|
||||
class CapabilityManager {
|
||||
@ -75,6 +76,7 @@ class CapabilityManager {
|
||||
return valid;
|
||||
},
|
||||
[InternalClientCapability.UserStatus]: async () => true, // No requirements for user status
|
||||
[InternalClientCapability.CloudSaves]: async () => true, // No requirements for cloud saves
|
||||
};
|
||||
|
||||
async validateCapabilityConfiguration(
|
||||
@ -82,6 +84,7 @@ class CapabilityManager {
|
||||
configuration: object
|
||||
) {
|
||||
const validationFunction = this.validationFunctions[capability];
|
||||
if (!validationFunction) return false;
|
||||
return validationFunction(configuration);
|
||||
}
|
||||
|
||||
@ -90,8 +93,11 @@ class CapabilityManager {
|
||||
rawCapability: object,
|
||||
clientId: string
|
||||
) {
|
||||
switch (capability) {
|
||||
case InternalClientCapability.PeerAPI:
|
||||
const upsertFunctions: EnumDictionary<
|
||||
InternalClientCapability,
|
||||
() => Promise<void> | void
|
||||
> = {
|
||||
[InternalClientCapability.PeerAPI]: async function () {
|
||||
const configuration =
|
||||
rawCapability as CapabilityConfiguration[InternalClientCapability.PeerAPI];
|
||||
|
||||
@ -127,9 +133,32 @@ class CapabilityManager {
|
||||
},
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
throw new Error("Cannot upsert client capability for: " + capability);
|
||||
},
|
||||
[InternalClientCapability.UserStatus]: function (): Promise<void> | void {
|
||||
throw new Error("Function not implemented.");
|
||||
},
|
||||
[InternalClientCapability.CloudSaves]: async function () {
|
||||
const currentClient = await prisma.client.findUnique({
|
||||
where: { id: clientId },
|
||||
select: {
|
||||
capabilities: true,
|
||||
},
|
||||
});
|
||||
if (!currentClient) throw new Error("Invalid client ID");
|
||||
if (currentClient.capabilities.includes(ClientCapabilities.CloudSaves))
|
||||
return;
|
||||
|
||||
await prisma.client.update({
|
||||
where: { id: clientId },
|
||||
data: {
|
||||
capabilities: {
|
||||
push: ClientCapabilities.CloudSaves,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
await upsertFunctions[capability]();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,16 @@ export function defineClientEventHandler<T>(handler: EventHandlerFunction<T>) {
|
||||
|
||||
let clientId: string;
|
||||
switch (method) {
|
||||
case "Debug":
|
||||
if (!process.dev) throw createError({ statusCode: 403 });
|
||||
const client = await prisma.client.findFirst({ select: { id: true } });
|
||||
if (!client)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No clients created.",
|
||||
});
|
||||
clientId = client.id;
|
||||
break;
|
||||
case "Nonce":
|
||||
clientId = parts[0];
|
||||
const nonce = parts[1];
|
||||
@ -49,7 +59,9 @@ export function defineClientEventHandler<T>(handler: EventHandlerFunction<T>) {
|
||||
}
|
||||
|
||||
const certificateAuthority = useCertificateAuthority();
|
||||
const certBundle = await certificateAuthority.fetchClientCertificate(clientId);
|
||||
const certBundle = await certificateAuthority.fetchClientCertificate(
|
||||
clientId
|
||||
);
|
||||
// This does the blacklist check already
|
||||
if (!certBundle)
|
||||
throw createError({
|
||||
|
||||
Reference in New Issue
Block a user