mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-10 04:22:09 +10:00
fix: eslint errors, switch to using maps
This commit is contained in:
@ -91,6 +91,4 @@ const navigation: NavigationItem[] = [
|
||||
prefix: "",
|
||||
},
|
||||
].filter((e) => e !== undefined);
|
||||
|
||||
const router = useRouter();
|
||||
</script>
|
||||
|
||||
@ -31,6 +31,7 @@ export const fetchNews = async (options?: {
|
||||
|
||||
const news = useNews();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore forget why this ignor exists
|
||||
const newValue = await $dropFetch(`/api/v1/news?${query.toString()}`);
|
||||
|
||||
|
||||
@ -17,6 +17,8 @@ interface DropFetch<
|
||||
request: R,
|
||||
opts?: O,
|
||||
): Promise<
|
||||
// sometimes there is an error, other times there isn't
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
TypedInternalResponse<
|
||||
R,
|
||||
@ -28,7 +30,7 @@ interface DropFetch<
|
||||
|
||||
export const $dropFetch: DropFetch = async (request, opts) => {
|
||||
if (!getCurrentInstance()?.proxy) {
|
||||
return (await $fetch(request, opts)) as any;
|
||||
return await $fetch(request, opts);
|
||||
}
|
||||
const id = request.toString();
|
||||
|
||||
@ -45,7 +47,7 @@ export const $dropFetch: DropFetch = async (request, opts) => {
|
||||
const data = await $fetch(request, {
|
||||
...opts,
|
||||
headers: { ...opts?.headers, ...headers },
|
||||
} as any);
|
||||
});
|
||||
if (import.meta.server) state.value = data;
|
||||
return data as any;
|
||||
return data;
|
||||
};
|
||||
|
||||
@ -7,33 +7,35 @@ import { randomUUID } from "node:crypto";
|
||||
import objectHandler from ".";
|
||||
|
||||
export type TransactionDataType = string | Readable | Buffer;
|
||||
type TransactionTable = { [key: string]: TransactionDataType }; // ID to data
|
||||
type GlobalTransactionRecord = { [key: string]: TransactionTable }; // Transaction ID to table
|
||||
type TransactionTable = Map<string, TransactionDataType>; // ID to data
|
||||
type GlobalTransactionRecord = Map<string, TransactionTable>; // Transaction ID to table
|
||||
|
||||
export type Register = (url: TransactionDataType) => string;
|
||||
export type Pull = () => Promise<void>;
|
||||
export type Dump = () => void;
|
||||
|
||||
export class ObjectTransactionalHandler {
|
||||
private record: GlobalTransactionRecord = {};
|
||||
private record: GlobalTransactionRecord = new Map();
|
||||
|
||||
new(
|
||||
metadata: { [key: string]: string },
|
||||
permissions: Array<string>
|
||||
permissions: Array<string>,
|
||||
): [Register, Pull, Dump] {
|
||||
const transactionId = randomUUID();
|
||||
|
||||
this.record[transactionId] ??= {};
|
||||
this.record.set(transactionId, new Map());
|
||||
|
||||
const register = (data: TransactionDataType) => {
|
||||
const objectId = randomUUID();
|
||||
this.record[transactionId][objectId] = data;
|
||||
this.record.get(transactionId)?.set(objectId, data);
|
||||
|
||||
return objectId;
|
||||
};
|
||||
|
||||
const pull = async () => {
|
||||
for (const [id, data] of Object.entries(this.record[transactionId])) {
|
||||
const transaction = this.record.get(transactionId);
|
||||
if (!transaction) return;
|
||||
for (const [id, data] of transaction) {
|
||||
await objectHandler.createFromSource(
|
||||
id,
|
||||
() => {
|
||||
@ -43,13 +45,13 @@ export class ObjectTransactionalHandler {
|
||||
return (async () => data)();
|
||||
},
|
||||
metadata,
|
||||
permissions
|
||||
permissions,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const dump = () => {
|
||||
delete this.record[transactionId];
|
||||
this.record.delete(transactionId);
|
||||
};
|
||||
|
||||
return [register, pull, dump];
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import Stream, { Readable } from "stream";
|
||||
import Stream from "stream";
|
||||
import prisma from "../db/database";
|
||||
import { applicationSettings } from "../config/application-configuration";
|
||||
import objectHandler from "../objects";
|
||||
@ -10,7 +10,7 @@ class SaveManager {
|
||||
gameId: string,
|
||||
userId: string,
|
||||
index: number,
|
||||
objectId: string
|
||||
objectId: string,
|
||||
) {
|
||||
await objectHandler.deleteWithPermission(objectId, userId);
|
||||
}
|
||||
@ -20,7 +20,7 @@ class SaveManager {
|
||||
userId: string,
|
||||
index: number,
|
||||
stream: IncomingMessage,
|
||||
clientId: string | undefined = undefined
|
||||
clientId: string | undefined = undefined,
|
||||
) {
|
||||
const save = await prisma.saveSlot.findUnique({
|
||||
where: {
|
||||
@ -38,7 +38,7 @@ class SaveManager {
|
||||
const newSaveStream = await objectHandler.createWithStream(
|
||||
newSaveObjectId,
|
||||
{ saveSlot: JSON.stringify({ userId, gameId, index }) },
|
||||
[]
|
||||
[],
|
||||
);
|
||||
if (!newSaveStream)
|
||||
throw createError({
|
||||
@ -51,10 +51,9 @@ class SaveManager {
|
||||
stream,
|
||||
createHash("sha256").setEncoding("hex"),
|
||||
async function (source) {
|
||||
// Not sure how to get this to be typed
|
||||
// @ts-expect-error
|
||||
// @ts-expect-error Not sure how to get this to be typed
|
||||
hash = (await source.toArray())[0];
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const uploadStream = Stream.promises.pipeline(stream, newSaveStream);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import bcrypt from "bcryptjs";
|
||||
import * as argon2 from "argon2";
|
||||
import { type } from "arktype";
|
||||
|
||||
export async function checkHashBcrypt(password: string, hash: string) {
|
||||
return await bcrypt.compare(password, hash);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { LRUCache } from "lru-cache";
|
||||
import prisma from "../db/database";
|
||||
import type { Session, SessionProvider } from "./types";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
export default function createDBSessionHandler(): SessionProvider {
|
||||
const cache = new LRUCache<string, Session>({
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { H3Event } from "h3";
|
||||
import createMemorySessionProvider from "./memory";
|
||||
import type { Session, SessionProvider } from "./types";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { parse as parseCookies } from "cookie-es";
|
||||
@ -90,7 +89,7 @@ export class SessionHandler {
|
||||
* @returns session token
|
||||
*/
|
||||
private getSessionToken(
|
||||
request: MinimumRequestObject | undefined
|
||||
request: MinimumRequestObject | undefined,
|
||||
): string | undefined {
|
||||
if (!request) throw new Error("Native web request not available");
|
||||
const cookieHeader = request.headers.get("Cookie");
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
import type { Session, SessionProvider } from "./types";
|
||||
|
||||
export default function createMemorySessionHandler() {
|
||||
const sessions: { [key: string]: Session } = {};
|
||||
const sessions = new Map<string, Session>();
|
||||
|
||||
const memoryProvider: SessionProvider = {
|
||||
async setSession(token, data) {
|
||||
sessions[token] = data;
|
||||
sessions.set(token, data);
|
||||
return true;
|
||||
},
|
||||
async getSession<T extends Session>(token: string): Promise<T | undefined> {
|
||||
const session = sessions[token];
|
||||
const session = sessions.get(token);
|
||||
return session ? (session as T) : undefined; // Ensure undefined is returned if session is not found
|
||||
},
|
||||
async updateSession(token, data) {
|
||||
return this.setSession(token, data);
|
||||
},
|
||||
async removeSession(token) {
|
||||
delete sessions[token];
|
||||
sessions.delete(token);
|
||||
return true;
|
||||
},
|
||||
async cleanupSessions() {
|
||||
const now = new Date();
|
||||
for (const token in sessions) {
|
||||
for (const [token, session] of sessions) {
|
||||
// if expires at time is before now, the session is expired
|
||||
if (sessions[token].expiresAt < now) await this.removeSession(token);
|
||||
if (session.expiresAt < now) await this.removeSession(token);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
3
server/internal/session/types.d.ts
vendored
3
server/internal/session/types.d.ts
vendored
@ -1,9 +1,8 @@
|
||||
import { H3Event } from "h3";
|
||||
|
||||
export type Session = {
|
||||
userId: string;
|
||||
expiresAt: Date;
|
||||
data: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any;
|
||||
};
|
||||
};
|
||||
|
||||
@ -13,18 +13,18 @@ type TaskRegistryEntry = {
|
||||
progress: number;
|
||||
log: string[];
|
||||
error: { title: string; description: string } | undefined;
|
||||
clients: { [key: string]: boolean };
|
||||
clients: Map<string, boolean>;
|
||||
name: string;
|
||||
acls: string[];
|
||||
};
|
||||
|
||||
class TaskHandler {
|
||||
private taskRegistry: { [key: string]: TaskRegistryEntry } = {};
|
||||
private clientRegistry: { [key: string]: PeerImpl } = {};
|
||||
// TODO: make these maps, using objects like this has performance impacts
|
||||
// https://typescript-eslint.io/rules/no-dynamic-delete/
|
||||
private taskRegistry = new Map<string, TaskRegistryEntry>();
|
||||
private clientRegistry = new Map<string, PeerImpl>();
|
||||
startTasks: (() => void)[] = [];
|
||||
|
||||
constructor() {}
|
||||
|
||||
create(task: Task) {
|
||||
let updateCollectTimeout: NodeJS.Timeout | undefined;
|
||||
let updateCollectResolves: Array<(value: unknown) => void> = [];
|
||||
@ -37,7 +37,7 @@ class TaskHandler {
|
||||
return;
|
||||
}
|
||||
updateCollectTimeout = setTimeout(() => {
|
||||
const taskEntry = this.taskRegistry[task.id];
|
||||
const taskEntry = this.taskRegistry.get(task.id);
|
||||
if (!taskEntry) return;
|
||||
|
||||
const taskMessage: TaskMessage = {
|
||||
@ -51,9 +51,10 @@ class TaskHandler {
|
||||
};
|
||||
logOffset = taskEntry.log.length;
|
||||
|
||||
for (const client of Object.keys(taskEntry.clients)) {
|
||||
if (!this.clientRegistry[client]) continue;
|
||||
this.clientRegistry[client].send(JSON.stringify(taskMessage));
|
||||
for (const clientId of Object.keys(taskEntry.clients)) {
|
||||
const client = this.clientRegistry.get(clientId);
|
||||
if (!client) continue;
|
||||
client.send(JSON.stringify(taskMessage));
|
||||
}
|
||||
updateCollectTimeout = undefined;
|
||||
|
||||
@ -66,65 +67,65 @@ class TaskHandler {
|
||||
});
|
||||
|
||||
const progress = (progress: number) => {
|
||||
const taskEntry = this.taskRegistry[task.id];
|
||||
const taskEntry = this.taskRegistry.get(task.id);
|
||||
if (!taskEntry) return;
|
||||
this.taskRegistry[task.id].progress = progress;
|
||||
taskEntry.progress = progress;
|
||||
updateAllClients();
|
||||
};
|
||||
|
||||
const log = (entry: string) => {
|
||||
const taskEntry = this.taskRegistry[task.id];
|
||||
const taskEntry = this.taskRegistry.get(task.id);
|
||||
if (!taskEntry) return;
|
||||
this.taskRegistry[task.id].log.push(entry);
|
||||
taskEntry.log.push(entry);
|
||||
updateAllClients();
|
||||
};
|
||||
|
||||
this.taskRegistry[task.id] = {
|
||||
this.taskRegistry.set(task.id, {
|
||||
name: task.name,
|
||||
success: false,
|
||||
progress: 0,
|
||||
error: undefined,
|
||||
log: [],
|
||||
clients: {},
|
||||
clients: new Map(),
|
||||
acls: task.acls,
|
||||
};
|
||||
});
|
||||
|
||||
updateAllClients(true);
|
||||
|
||||
droplet.callAltThreadFunc(async () => {
|
||||
const taskEntry = this.taskRegistry[task.id];
|
||||
const taskEntry = this.taskRegistry.get(task.id);
|
||||
if (!taskEntry) throw new Error("No task entry");
|
||||
|
||||
try {
|
||||
await task.run({ progress, log });
|
||||
this.taskRegistry[task.id].success = true;
|
||||
taskEntry.success = true;
|
||||
} catch (error: unknown) {
|
||||
this.taskRegistry[task.id].success = false;
|
||||
this.taskRegistry[task.id].error = {
|
||||
taskEntry.success = false;
|
||||
taskEntry.error = {
|
||||
title: "An error occurred",
|
||||
description: (error as string).toString(),
|
||||
};
|
||||
}
|
||||
await updateAllClients();
|
||||
|
||||
for (const client of Object.keys(taskEntry.clients)) {
|
||||
if (!this.clientRegistry[client]) continue;
|
||||
this.disconnect(client, task.id);
|
||||
for (const clientId of Object.keys(taskEntry.clients)) {
|
||||
if (!this.clientRegistry.get(clientId)) continue;
|
||||
this.disconnect(clientId, task.id);
|
||||
}
|
||||
delete this.taskRegistry[task.id];
|
||||
this.taskRegistry.delete(task.id);
|
||||
});
|
||||
}
|
||||
|
||||
async connect(
|
||||
id: string,
|
||||
clientId: string,
|
||||
taskId: string,
|
||||
peer: PeerImpl,
|
||||
request: MinimumRequestObject
|
||||
request: MinimumRequestObject,
|
||||
) {
|
||||
const task = this.taskRegistry[taskId];
|
||||
const task = this.taskRegistry.get(taskId);
|
||||
if (!task) {
|
||||
peer.send(
|
||||
`error/${taskId}/Unknown task/Drop couldn't find the task you're looking for.`
|
||||
`error/${taskId}/Unknown task/Drop couldn't find the task you're looking for.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -133,13 +134,13 @@ class TaskHandler {
|
||||
if (!allowed) {
|
||||
console.warn("user does not have necessary ACLs");
|
||||
peer.send(
|
||||
`error/${taskId}/Unknown task/Drop couldn't find the task you're looking for.`
|
||||
`error/${taskId}/Unknown task/Drop couldn't find the task you're looking for.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.clientRegistry[id] = peer;
|
||||
this.taskRegistry[taskId].clients[id] = true; // Uniquely insert client to avoid sending duplicate traffic
|
||||
this.clientRegistry.set(clientId, peer);
|
||||
task.clients.set(clientId, true); // Uniquely insert client to avoid sending duplicate traffic
|
||||
|
||||
const catchupMessage: TaskMessage = {
|
||||
id: taskId,
|
||||
@ -153,24 +154,25 @@ class TaskHandler {
|
||||
}
|
||||
|
||||
sendDisconnectEvent(id: string, taskId: string) {
|
||||
const client = this.clientRegistry[id];
|
||||
const client = this.clientRegistry.get(id);
|
||||
if (!client) return;
|
||||
client.send(`disconnect/${taskId}`);
|
||||
}
|
||||
|
||||
disconnectAll(id: string) {
|
||||
for (const taskId of Object.keys(this.taskRegistry)) {
|
||||
delete this.taskRegistry[taskId].clients[id];
|
||||
this.taskRegistry.get(taskId)?.clients.delete(id);
|
||||
this.sendDisconnectEvent(id, taskId);
|
||||
}
|
||||
|
||||
delete this.clientRegistry[id];
|
||||
this.clientRegistry.delete(id);
|
||||
}
|
||||
|
||||
disconnect(id: string, taskId: string) {
|
||||
if (!this.taskRegistry[taskId]) return false;
|
||||
const task = this.taskRegistry.get(taskId);
|
||||
if (!task) return false;
|
||||
|
||||
delete this.taskRegistry[taskId].clients[id];
|
||||
task.clients.delete(id);
|
||||
this.sendDisconnectEvent(id, taskId);
|
||||
|
||||
const allClientIds = Object.values(this.taskRegistry)
|
||||
@ -178,7 +180,7 @@ class TaskHandler {
|
||||
.flat();
|
||||
|
||||
if (!allClientIds.includes(id)) {
|
||||
delete this.clientRegistry[id];
|
||||
this.clientRegistry.delete(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -8,8 +8,6 @@ class UserLibraryManager {
|
||||
// Caches the user's core library
|
||||
private userCoreLibraryCache: { [key: string]: string } = {};
|
||||
|
||||
constructor() {}
|
||||
|
||||
private async fetchUserLibrary(userId: string) {
|
||||
if (this.userCoreLibraryCache[userId])
|
||||
return this.userCoreLibraryCache[userId];
|
||||
|
||||
@ -1,89 +1,93 @@
|
||||
import type { FilterConditionally } from "./types";
|
||||
|
||||
interface PriorityTagged<T> {
|
||||
object: T,
|
||||
priority: number, // Higher takes priority
|
||||
addedIndex: number, // Lower takes priority
|
||||
object: T;
|
||||
priority: number; // Higher takes priority
|
||||
addedIndex: number; // Lower takes priority
|
||||
}
|
||||
|
||||
export class PriorityList<T> {
|
||||
private source: Array<PriorityTagged<T>> = [];
|
||||
private cachedSorted: Array<T> | undefined;
|
||||
private source: Array<PriorityTagged<T>> = [];
|
||||
private cachedSorted: Array<T> | undefined;
|
||||
|
||||
push(item: T, priority: number = 0) {
|
||||
this.source.push({
|
||||
object: item,
|
||||
priority,
|
||||
addedIndex: this.source.length,
|
||||
});
|
||||
this.cachedSorted = undefined;
|
||||
push(item: T, priority: number = 0) {
|
||||
this.source.push({
|
||||
object: item,
|
||||
priority,
|
||||
addedIndex: this.source.length,
|
||||
});
|
||||
this.cachedSorted = undefined;
|
||||
}
|
||||
|
||||
pop(index: number = 0) {
|
||||
this.cachedSorted = undefined;
|
||||
return this.source.splice(index, 1)[0];
|
||||
}
|
||||
|
||||
values() {
|
||||
if (this.cachedSorted !== undefined) {
|
||||
return this.cachedSorted;
|
||||
}
|
||||
|
||||
pop(index: number = 0) {
|
||||
this.cachedSorted = undefined;
|
||||
return this.source.splice(index, 1)[0];
|
||||
}
|
||||
|
||||
values() {
|
||||
if (this.cachedSorted !== undefined) {
|
||||
return this.cachedSorted;
|
||||
const sorted = this.source
|
||||
.sort((a, b) => {
|
||||
if (a.priority == a.priority) {
|
||||
return a.addedIndex - b.addedIndex;
|
||||
}
|
||||
|
||||
const sorted = this.source.sort((a, b) => {
|
||||
if (a.priority == a.priority) {
|
||||
return a.addedIndex - b.addedIndex;
|
||||
}
|
||||
return b.priority - a.priority;
|
||||
})
|
||||
.map((e) => e.object);
|
||||
this.cachedSorted = sorted;
|
||||
|
||||
return b.priority - a.priority;
|
||||
}).map((e) => e.object);
|
||||
this.cachedSorted = sorted;
|
||||
return this.cachedSorted;
|
||||
}
|
||||
|
||||
return this.cachedSorted;
|
||||
}
|
||||
|
||||
find(predicate: (value: T, index: number, obj: T[]) => boolean) {
|
||||
return this.source.map((e) => e.object).find(predicate);
|
||||
}
|
||||
find(predicate: (value: T, index: number, obj: T[]) => boolean) {
|
||||
return this.source.map((e) => e.object).find(predicate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
type IndexableProperty<T> = keyof FilterConditionally<T, (() => string) | string>;
|
||||
type IndexableProperty<T> = keyof FilterConditionally<
|
||||
T,
|
||||
(() => string) | string
|
||||
>;
|
||||
export class PriorityListIndexed<T> extends PriorityList<T> {
|
||||
private indexName: IndexableProperty<T>;
|
||||
private indexMap: { [key: string]: T } = {};
|
||||
private indexName: IndexableProperty<T>;
|
||||
private indexMap = new Map<string, T>();
|
||||
|
||||
constructor(indexName: IndexableProperty<T>) {
|
||||
super();
|
||||
this.indexName = indexName;
|
||||
constructor(indexName: IndexableProperty<T>) {
|
||||
super();
|
||||
this.indexName = indexName;
|
||||
}
|
||||
|
||||
private getIndex(object: T): string {
|
||||
const index = object[this.indexName];
|
||||
|
||||
if (typeof index === "function") {
|
||||
return index();
|
||||
}
|
||||
|
||||
private getIndex(object: T): string {
|
||||
const index = object[this.indexName];
|
||||
return index as string;
|
||||
}
|
||||
|
||||
if (typeof index === 'function') {
|
||||
return index();
|
||||
}
|
||||
override push(item: T, priority?: number): void {
|
||||
const index = this.getIndex(item);
|
||||
this.indexMap.set(index, item);
|
||||
|
||||
return index as string;
|
||||
}
|
||||
super.push(item, priority);
|
||||
}
|
||||
|
||||
override push(item: T, priority?: number): void {
|
||||
const index = this.getIndex(item);
|
||||
this.indexMap[index] = item;
|
||||
override pop(position?: number): PriorityTagged<T> {
|
||||
const value = super.pop(position);
|
||||
|
||||
super.push(item, priority);
|
||||
}
|
||||
const index = this.getIndex(value.object);
|
||||
this.indexMap.delete(index);
|
||||
|
||||
override pop(position?: number): PriorityTagged<T> {
|
||||
const value = super.pop(position);
|
||||
return value;
|
||||
}
|
||||
|
||||
const index = this.getIndex(value.object);
|
||||
delete this.indexMap[index];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
get(index: string) {
|
||||
return this.indexMap[index];
|
||||
}
|
||||
}
|
||||
get(index: string) {
|
||||
return this.indexMap.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
2
server/internal/utils/types.d.ts
vendored
2
server/internal/utils/types.d.ts
vendored
@ -3,6 +3,8 @@ export type FilterConditionally<Source, Condition> = Pick<
|
||||
{ [K in keyof Source]: Source[K] extends Condition ? K : never }[keyof Source]
|
||||
>;
|
||||
export type KeyOfType<T, V> = keyof {
|
||||
// TODO: should switch to unknown??
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[P in keyof T as T[P] extends V ? P : never]: any;
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { applicationSettings } from "../internal/config/application-configuration";
|
||||
import prisma from "../internal/db/database";
|
||||
|
||||
export default defineNitroPlugin(async (nitro) => {
|
||||
export default defineNitroPlugin(async () => {
|
||||
// Ensure system user exists
|
||||
// The system user owns any user-based code
|
||||
// that we want to re-use for the app
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import prisma from "../internal/db/database";
|
||||
|
||||
export default defineNitroPlugin(async (nitro) => {
|
||||
export default defineNitroPlugin(async () => {
|
||||
const userCount = await prisma.user.count({
|
||||
where: { id: { not: "system" } },
|
||||
});
|
||||
|
||||
@ -6,20 +6,20 @@ import { IGDBProvider } from "../internal/metadata/igdb";
|
||||
import { ManualMetadataProvider } from "../internal/metadata/manual";
|
||||
import { PCGamingWikiProvider } from "../internal/metadata/pcgamingwiki";
|
||||
|
||||
export default defineNitroPlugin(async (nitro) => {
|
||||
export default defineNitroPlugin(async () => {
|
||||
const metadataProviders = [
|
||||
GiantBombProvider,
|
||||
PCGamingWikiProvider,
|
||||
IGDBProvider,
|
||||
];
|
||||
|
||||
const providers: { [key: string]: MetadataProvider } = {};
|
||||
const providers = new Map<string, MetadataProvider>();
|
||||
|
||||
for (const provider of metadataProviders) {
|
||||
try {
|
||||
const prov = new provider();
|
||||
const id = prov.id();
|
||||
providers[id] = prov;
|
||||
providers.set(id, prov);
|
||||
|
||||
console.log(`enabled metadata provider: ${prov.name()}`);
|
||||
} catch (e) {
|
||||
@ -28,23 +28,22 @@ export default defineNitroPlugin(async (nitro) => {
|
||||
}
|
||||
|
||||
// Add providers based on their position in the application settings
|
||||
const configuredProviderList = await applicationSettings.get(
|
||||
"metadataProviders"
|
||||
);
|
||||
const configuredProviderList =
|
||||
await applicationSettings.get("metadataProviders");
|
||||
const max = configuredProviderList.length;
|
||||
for (const [index, providerId] of configuredProviderList.entries()) {
|
||||
const priority = max * 2 - index; // Offset by the length --- (max - index) + max
|
||||
const provider = providers[providerId];
|
||||
const provider = providers.get(providerId);
|
||||
if (!provider) {
|
||||
console.warn(`failed to add existing metadata provider: ${providerId}`);
|
||||
continue;
|
||||
}
|
||||
metadataHandler.addProvider(provider, priority);
|
||||
delete providers[providerId];
|
||||
providers.delete(providerId);
|
||||
}
|
||||
|
||||
// Add the rest with no position
|
||||
for (const [providerId, provider] of Object.entries(providers)) {
|
||||
for (const [, provider] of Object.entries(providers)) {
|
||||
metadataHandler.addProvider(provider);
|
||||
}
|
||||
|
||||
@ -53,6 +52,6 @@ export default defineNitroPlugin(async (nitro) => {
|
||||
// Update the applicatonConfig
|
||||
await applicationSettings.set(
|
||||
"metadataProviders",
|
||||
metadataHandler.fetchProviderIdsInOrder()
|
||||
metadataHandler.fetchProviderIdsInOrder(),
|
||||
);
|
||||
});
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
import { CertificateAuthority } from "../internal/clients/ca";
|
||||
import fs from "fs";
|
||||
import {
|
||||
dbCertificateStore,
|
||||
fsCertificateStore,
|
||||
} from "../internal/clients/ca-store";
|
||||
import { dbCertificateStore } from "../internal/clients/ca-store";
|
||||
|
||||
let ca: CertificateAuthority | undefined;
|
||||
|
||||
@ -12,7 +8,7 @@ export const useCertificateAuthority = () => {
|
||||
return ca;
|
||||
};
|
||||
|
||||
export default defineNitroPlugin(async (nitro) => {
|
||||
export default defineNitroPlugin(async () => {
|
||||
// const basePath = process.env.CLIENT_CERTIFICATES ?? "./certs";
|
||||
// fs.mkdirSync(basePath, { recursive: true });
|
||||
// const store = fsCertificateStore(basePath);
|
||||
|
||||
@ -13,13 +13,14 @@ export default defineNitroPlugin((nitro) => {
|
||||
|
||||
switch (error.statusCode) {
|
||||
case 401:
|
||||
case 403:
|
||||
case 403: {
|
||||
const user = await sessionHandler.getSession(event);
|
||||
if (user) break;
|
||||
return sendRedirect(
|
||||
event,
|
||||
`/auth/signin?redirect=${encodeURIComponent(event.path)}`
|
||||
`/auth/signin?redirect=${encodeURIComponent(event.path)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -4,7 +4,7 @@ export default defineTask({
|
||||
meta: {
|
||||
name: "cleanup:invitations",
|
||||
},
|
||||
async run({}) {
|
||||
async run() {
|
||||
const now = new Date();
|
||||
|
||||
await prisma.invitation.deleteMany({
|
||||
|
||||
@ -4,7 +4,7 @@ export default defineTask({
|
||||
meta: {
|
||||
name: "cleanup:invitations",
|
||||
},
|
||||
async run({}) {
|
||||
async run() {
|
||||
await sessionHandler.cleanupSessions();
|
||||
|
||||
return { result: true };
|
||||
|
||||
Reference in New Issue
Block a user