wip importer
This commit is contained in:
committed by
Carl-Gerhard Lindesvärd
parent
ba381636a0
commit
da856152c7
39
apps/api/src/controllers/import.controller.ts
Normal file
39
apps/api/src/controllers/import.controller.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { pathOr } from 'ramda';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { toDots } from '@openpanel/common';
|
||||
import type {
|
||||
IClickhouseEvent,
|
||||
IServiceCreateEventPayload,
|
||||
} from '@openpanel/db';
|
||||
import { ch, formatClickhouseDate } from '@openpanel/db';
|
||||
import type { PostEventPayload } from '@openpanel/sdk';
|
||||
|
||||
export async function importEvents(
|
||||
request: FastifyRequest<{
|
||||
Body: IClickhouseEvent[];
|
||||
}>,
|
||||
reply: FastifyReply
|
||||
) {
|
||||
console.log('HERE?!', request.body.length);
|
||||
|
||||
const values: IClickhouseEvent[] = request.body.map((event) => {
|
||||
return {
|
||||
...event,
|
||||
project_id: request.client?.projectId ?? '',
|
||||
created_at: formatClickhouseDate(event.created_at),
|
||||
};
|
||||
});
|
||||
|
||||
const res = await ch.insert({
|
||||
table: 'events',
|
||||
values,
|
||||
format: 'JSONEachRow',
|
||||
clickhouse_settings: {
|
||||
date_time_input_format: 'best_effort',
|
||||
},
|
||||
});
|
||||
|
||||
reply.send('OK');
|
||||
}
|
||||
38
apps/api/src/routes/import.router.ts
Normal file
38
apps/api/src/routes/import.router.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import * as controller from '@/controllers/import.controller';
|
||||
import { validateImportRequest } from '@/utils/auth';
|
||||
import type { FastifyPluginCallback, FastifyRequest } from 'fastify';
|
||||
|
||||
import { Prisma } from '@openpanel/db';
|
||||
|
||||
const importRouter: FastifyPluginCallback = (fastify, opts, done) => {
|
||||
fastify.addHook('preHandler', async (req: FastifyRequest, reply) => {
|
||||
try {
|
||||
const client = await validateImportRequest(req.headers);
|
||||
req.client = client;
|
||||
} catch (e) {
|
||||
if (e instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
return reply.status(401).send({
|
||||
error: 'Unauthorized',
|
||||
message: 'Client ID seems to be malformed',
|
||||
});
|
||||
} else if (e instanceof Error) {
|
||||
return reply
|
||||
.status(401)
|
||||
.send({ error: 'Unauthorized', message: e.message });
|
||||
}
|
||||
return reply
|
||||
.status(401)
|
||||
.send({ error: 'Unauthorized', message: 'Unexpected error' });
|
||||
}
|
||||
});
|
||||
|
||||
fastify.route({
|
||||
method: 'POST',
|
||||
url: '/events',
|
||||
handler: controller.importEvents,
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
||||
|
||||
export default importRouter;
|
||||
@@ -128,6 +128,36 @@ export async function validateExportRequest(
|
||||
return client;
|
||||
}
|
||||
|
||||
export async function validateImportRequest(
|
||||
headers: RawRequestDefaultExpression['headers']
|
||||
): Promise<IServiceClient> {
|
||||
const clientId = headers['openpanel-client-id'] as string;
|
||||
const clientSecret = (headers['openpanel-client-secret'] as string) || '';
|
||||
const client = await db.client.findUnique({
|
||||
where: {
|
||||
id: clientId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!client) {
|
||||
throw new Error('Import: Invalid client id');
|
||||
}
|
||||
|
||||
if (!client.secret) {
|
||||
throw new Error('Import: Client has no secret');
|
||||
}
|
||||
|
||||
if (client.type === ClientType.write) {
|
||||
throw new Error('Import: Client is not allowed to import');
|
||||
}
|
||||
|
||||
if (!(await verifyPassword(clientSecret, client.secret))) {
|
||||
throw new Error('Import: Invalid client secret');
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
export function validateClerkJwt(token?: string) {
|
||||
if (!token) {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user