Rework file access and link archiving

This commit is contained in:
2024-12-01 23:25:33 +01:00
parent f7094f7ce1
commit 602b0af212
14 changed files with 186 additions and 151 deletions

View File

@@ -1,47 +0,0 @@
import { and, eq, like, sql } from 'drizzle-orm';
import useDatabase from '~/composables/useDatabase';
import { explorerContentTable } from '~/db/schema';
export default defineEventHandler(async (e) => {
const query = getQuery(e);
const where = [];
if(query && query.path !== undefined)
{
where.push(eq(explorerContentTable.path, sql.placeholder('path')));
}
if(query && query.title !== undefined)
{
where.push(eq(explorerContentTable.title, sql.placeholder('title')));
}
if(query && query.type !== undefined)
{
where.push(eq(explorerContentTable.type, sql.placeholder('type')));
}
if (query && query.search !== undefined)
{
where.push(like(explorerContentTable.path, sql.placeholder('search')));
}
if(where.length > 0)
{
const db = useDatabase();
const content = db.select({
'path': explorerContentTable.path,
'owner': explorerContentTable.owner,
'title': explorerContentTable.title,
'type': explorerContentTable.type,
'content': sql<string>`cast(${explorerContentTable.content} as TEXT)`.as('content'),
'navigable': explorerContentTable.navigable,
'private': explorerContentTable.private,
}).from(explorerContentTable).where(and(...where)).prepare().all(query);
if(content.length > 0)
{
return content;
}
}
setResponseStatus(e, 404);
});

View File

@@ -1,6 +1,7 @@
import useDatabase from '~/composables/useDatabase';
import { explorerContentTable } from '~/db/schema';
import { schema } from '~/schemas/file';
import { parsePath } from '~/shared/general.utils';
export default defineEventHandler(async (e) => {
const body = await readValidatedBody(e, schema.safeParse);
@@ -10,9 +11,10 @@ export default defineEventHandler(async (e) => {
throw body.error;
}
const buffer = Buffer.from(body.data.content, 'utf-8');
const db = useDatabase();
const buffer = Buffer.from(convertToStorableLinks(body.data.content, db.select({ path: explorerContentTable.path }).from(explorerContentTable).all().map(e => e.path)), 'utf-8');
const content = db.insert(explorerContentTable).values({ ...body.data, content: buffer }).onConflictDoUpdate({ target: explorerContentTable.path, set: { ...body.data, content: buffer, timestamp: new Date() } });
if(content !== undefined)
@@ -22,4 +24,14 @@ export default defineEventHandler(async (e) => {
setResponseStatus(e, 404);
return;
});
});
export function convertToStorableLinks(content: string, path: string[]): string
{
return content.replaceAll(/!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/g, (e: string, a1?: string, a2?: string , a3?: string) => {
const parsed = parsePath(a1 ?? '%%%%----%%%%----%%%%');
const replacer = path.find(e => e.endsWith(parsed));
const value = `[[${replacer ?? ''}${a2 ?? ''}${(!a3 && replacer !== parsed ? '|' + a1 : a3) ?? ''}]]`;
return value;
});
}

View File

@@ -0,0 +1,62 @@
import { eq, sql } from 'drizzle-orm';
import useDatabase from '~/composables/useDatabase';
import { explorerContentTable } from '~/db/schema';
export default defineEventHandler(async (e) => {
const path = decodeURIComponent(getRouterParam(e, "path") ?? '');
const query = getQuery(e);
if(!path)
{
setResponseStatus(e, 404);
return;
}
const db = useDatabase();
const content = db.select({
'content': sql<string>`cast(${explorerContentTable.content} as TEXT)`.as('content'),
'private': explorerContentTable.private,
'owner': explorerContentTable.owner,
'visit': explorerContentTable.visit,
}).from(explorerContentTable).where(eq(explorerContentTable.path, sql.placeholder('path'))).prepare().get({ path });
if(content !== undefined)
{
const session = await getUserSession(e);
if(content.private && (!session || !session.user))
{
setResponseStatus(e, 404);
return;
}
if(session && session.user && content.private && session.user.id !== content.owner)
{
setResponseStatus(e, 404);
return;
}
if(query.type === 'view')
{
db.update(explorerContentTable).set({ visit: content.visit + 1 }).where(eq(explorerContentTable.path, path)).run();
}
if(query.type === 'editing')
{
content.content = convertFromStorableLinks(content.content);
}
return { content: content.content };
}
setResponseStatus(e, 404);
return;
});
export function convertFromStorableLinks(content: string): string
{
/*return content.replaceAll(/!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\|\#]+)?\]\]/g, (e: string, a1?: string, a2?: string , a3?: string) => {
const parsed = parsePath(a1 ?? '%%%%----%%%%----%%%%');
const replacer = path.find(e => e.endsWith(parsed)) ?? parsed;
const value = `[[${replacer}${a2 ?? ''}${(!a3 && replacer !== parsed ? '|' + a1 : a3) ?? ''}]]`;
return value;
});*/
return content;
}

View File

@@ -18,7 +18,6 @@ export default defineEventHandler(async (e) => {
'owner': explorerContentTable.owner,
'title': explorerContentTable.title,
'type': explorerContentTable.type,
'content': sql<string>`cast(${explorerContentTable.content} as TEXT)`.as('content'),
'navigable': explorerContentTable.navigable,
'private': explorerContentTable.private,
'order': explorerContentTable.order,
@@ -27,8 +26,19 @@ export default defineEventHandler(async (e) => {
if(content !== undefined)
{
db.update(explorerContentTable).set({ visit: content.visit + 1 }).where(eq(explorerContentTable.path, content.path)).run();
const session = await getUserSession(e);
if(content.private && (!session || !session.user))
{
setResponseStatus(e, 404);
return;
}
if(session && session.user && content.private && session.user.id !== content.owner)
{
setResponseStatus(e, 404);
return;
}
return content;
}