mirror of
https://github.com/movie-web/backend.git
synced 2025-09-13 18:13:26 +00:00
fix bugs + add a lot of endpoints
Co-authored-by: William Oldham <github@binaryoverload.co.uk>
This commit is contained in:
39
src/routes/auth/login.ts
Normal file
39
src/routes/auth/login.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { formatSession } from '@/db/models/Session';
|
||||
import { User } from '@/db/models/User';
|
||||
import { StatusError } from '@/services/error';
|
||||
import { handle } from '@/services/handler';
|
||||
import { makeRouter } from '@/services/router';
|
||||
import { makeSession, makeSessionToken } from '@/services/session';
|
||||
import { z } from 'zod';
|
||||
|
||||
const loginSchema = z.object({
|
||||
id: z.string(),
|
||||
device: z.string().max(500).min(1),
|
||||
});
|
||||
|
||||
export const loginAuthRouter = makeRouter((app) => {
|
||||
app.post(
|
||||
'/auth/login',
|
||||
{ schema: { body: loginSchema } },
|
||||
handle(async ({ em, body, req }) => {
|
||||
const user = await em.findOne(User, { id: body.id });
|
||||
|
||||
if (user == null) {
|
||||
throw new StatusError('User cannot be found', 401);
|
||||
}
|
||||
|
||||
const session = makeSession(
|
||||
user.id,
|
||||
body.device,
|
||||
req.headers['user-agent'],
|
||||
);
|
||||
|
||||
await em.persistAndFlush(session);
|
||||
|
||||
return {
|
||||
session: formatSession(session),
|
||||
token: makeSessionToken(session),
|
||||
};
|
||||
}),
|
||||
);
|
||||
});
|
@@ -8,6 +8,11 @@ import { z } from 'zod';
|
||||
const registerSchema = z.object({
|
||||
name: z.string().max(500).min(1),
|
||||
device: z.string().max(500).min(1),
|
||||
profile: z.object({
|
||||
colorA: z.string(),
|
||||
colorB: z.string(),
|
||||
icon: z.string(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const manageAuthRouter = makeRouter((app) => {
|
||||
@@ -17,14 +22,15 @@ export const manageAuthRouter = makeRouter((app) => {
|
||||
handle(async ({ em, body, req }) => {
|
||||
const user = new User();
|
||||
user.name = body.name;
|
||||
user.profile = body.profile;
|
||||
|
||||
const session = makeSession(
|
||||
user.id,
|
||||
body.device,
|
||||
req.headers['user-agent'],
|
||||
);
|
||||
|
||||
em.persist([user, session]);
|
||||
await em.flush();
|
||||
await em.persistAndFlush([user, session]);
|
||||
|
||||
return {
|
||||
user: formatUser(user),
|
||||
|
@@ -4,9 +4,9 @@ import { handle } from '@/services/handler';
|
||||
import { makeRouter } from '@/services/router';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const sessionRouter = makeRouter((app) => {
|
||||
export const authSessionRouter = makeRouter((app) => {
|
||||
app.delete(
|
||||
'/auth/session/:sid',
|
||||
'/sessions/:sid',
|
||||
{
|
||||
schema: {
|
||||
params: z.object({
|
||||
@@ -15,16 +15,21 @@ export const sessionRouter = makeRouter((app) => {
|
||||
},
|
||||
},
|
||||
handle(async ({ auth, params, em }) => {
|
||||
auth.assert();
|
||||
await auth.assert();
|
||||
|
||||
const targetedSession = await em.findOne(Session, { id: params.sid });
|
||||
if (!targetedSession) return true; // already deleted
|
||||
if (!targetedSession)
|
||||
return {
|
||||
id: params.sid,
|
||||
};
|
||||
|
||||
if (targetedSession.user !== auth.user.id)
|
||||
throw new StatusError('Cant delete sessions you dont own', 401);
|
||||
throw new StatusError('Cannot delete sessions you do not own', 401);
|
||||
|
||||
await em.removeAndFlush(targetedSession);
|
||||
return true;
|
||||
return {
|
||||
id: params.sid,
|
||||
};
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
28
src/routes/meta.ts
Normal file
28
src/routes/meta.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { conf } from '@/config';
|
||||
import { handle } from '@/services/handler';
|
||||
import { makeRouter } from '@/services/router';
|
||||
|
||||
export const metaRouter = makeRouter((app) => {
|
||||
app.get(
|
||||
'/healthcheck',
|
||||
handle(async ({ em }) => {
|
||||
const databaseConnected = await em.config
|
||||
.getDriver()
|
||||
.getConnection()
|
||||
.isConnected();
|
||||
return {
|
||||
healthy: databaseConnected,
|
||||
databaseConnected,
|
||||
};
|
||||
}),
|
||||
);
|
||||
app.get(
|
||||
'/meta',
|
||||
handle(async () => {
|
||||
return {
|
||||
name: conf.meta.name,
|
||||
description: conf.meta.description,
|
||||
};
|
||||
}),
|
||||
);
|
||||
});
|
65
src/routes/sessions.ts
Normal file
65
src/routes/sessions.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { Session, formatSession } from '@/db/models/Session';
|
||||
import { StatusError } from '@/services/error';
|
||||
import { handle } from '@/services/handler';
|
||||
import { makeRouter } from '@/services/router';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const sessionsRouter = makeRouter((app) => {
|
||||
app.patch(
|
||||
'/sessions/:sid',
|
||||
{
|
||||
schema: {
|
||||
params: z.object({
|
||||
sid: z.string(),
|
||||
}),
|
||||
body: z.object({
|
||||
name: z.string().max(500).min(1).optional(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handle(async ({ auth, params, em, body }) => {
|
||||
await auth.assert();
|
||||
|
||||
const targetedSession = await em.findOne(Session, { id: params.sid });
|
||||
|
||||
if (!targetedSession)
|
||||
throw new StatusError('Session cannot be found', 404);
|
||||
|
||||
if (targetedSession.user !== auth.user.id)
|
||||
throw new StatusError('Cannot modify sessions you do not own', 401);
|
||||
|
||||
if (body.name) targetedSession.device = body.name;
|
||||
|
||||
await em.persistAndFlush(targetedSession);
|
||||
|
||||
return formatSession(targetedSession);
|
||||
}),
|
||||
);
|
||||
app.delete(
|
||||
'/sessions/:sid',
|
||||
{
|
||||
schema: {
|
||||
params: z.object({
|
||||
sid: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handle(async ({ auth, params, em }) => {
|
||||
await auth.assert();
|
||||
|
||||
const targetedSession = await em.findOne(Session, { id: params.sid });
|
||||
if (!targetedSession)
|
||||
return {
|
||||
id: params.sid,
|
||||
};
|
||||
|
||||
if (targetedSession.user !== auth.user.id)
|
||||
throw new StatusError('Cannot delete sessions you do not own', 401);
|
||||
|
||||
await em.removeAndFlush(targetedSession);
|
||||
return {
|
||||
id: params.sid,
|
||||
};
|
||||
}),
|
||||
);
|
||||
});
|
35
src/routes/sessions/session.ts
Normal file
35
src/routes/sessions/session.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Session } from '@/db/models/Session';
|
||||
import { StatusError } from '@/services/error';
|
||||
import { handle } from '@/services/handler';
|
||||
import { makeRouter } from '@/services/router';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const sessionRouter = makeRouter((app) => {
|
||||
app.delete(
|
||||
'/sessions/:sid',
|
||||
{
|
||||
schema: {
|
||||
params: z.object({
|
||||
sid: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handle(async ({ auth, params, em }) => {
|
||||
await auth.assert();
|
||||
|
||||
const targetedSession = await em.findOne(Session, { id: params.sid });
|
||||
if (!targetedSession)
|
||||
return {
|
||||
id: params.sid,
|
||||
};
|
||||
|
||||
if (targetedSession.user !== auth.user.id)
|
||||
throw new StatusError('Cannot delete sessions you do not own', 401);
|
||||
|
||||
await em.removeAndFlush(targetedSession);
|
||||
return {
|
||||
id: params.sid,
|
||||
};
|
||||
}),
|
||||
);
|
||||
});
|
36
src/routes/users/delete.ts
Normal file
36
src/routes/users/delete.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Session } from '@/db/models/Session';
|
||||
import { User } from '@/db/models/User';
|
||||
import { StatusError } from '@/services/error';
|
||||
import { handle } from '@/services/handler';
|
||||
import { makeRouter } from '@/services/router';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const userDeleteRouter = makeRouter((app) => {
|
||||
app.delete(
|
||||
'/users/:uid',
|
||||
{
|
||||
schema: {
|
||||
params: z.object({
|
||||
uid: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handle(async ({ auth, params, em }) => {
|
||||
await auth.assert();
|
||||
|
||||
const user = await em.findOne(User, { id: params.uid });
|
||||
if (!user) throw new StatusError('User does not exist', 404);
|
||||
|
||||
if (auth.user.id !== user.id)
|
||||
throw new StatusError('Cannot delete user other than yourself', 403);
|
||||
|
||||
const sessions = await em.find(Session, { user: user.id });
|
||||
|
||||
await em.remove([user, ...sessions]);
|
||||
await em.flush();
|
||||
return {
|
||||
id: user.id,
|
||||
};
|
||||
}),
|
||||
);
|
||||
});
|
43
src/routes/users/edit.ts
Normal file
43
src/routes/users/edit.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { User, formatUser } from '@/db/models/User';
|
||||
import { StatusError } from '@/services/error';
|
||||
import { handle } from '@/services/handler';
|
||||
import { makeRouter } from '@/services/router';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const userEditRouter = makeRouter((app) => {
|
||||
app.patch(
|
||||
'/users/:uid',
|
||||
{
|
||||
schema: {
|
||||
params: z.object({
|
||||
uid: z.string(),
|
||||
}),
|
||||
body: z.object({
|
||||
profile: z
|
||||
.object({
|
||||
colorA: z.string(),
|
||||
colorB: z.string(),
|
||||
icon: z.string(),
|
||||
})
|
||||
.optional(),
|
||||
name: z.string().max(500).min(1).optional(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handle(async ({ auth, params, body, em }) => {
|
||||
await auth.assert();
|
||||
|
||||
const user = await em.findOne(User, { id: params.uid });
|
||||
if (!user) throw new StatusError('User does not exist', 404);
|
||||
|
||||
if (auth.user.id !== user.id)
|
||||
throw new StatusError('Cannot modify user other than yourself', 403);
|
||||
|
||||
if (body.name) user.name = body.name;
|
||||
if (body.profile) user.profile = body.profile;
|
||||
|
||||
await em.persistAndFlush(user);
|
||||
return formatUser(user);
|
||||
}),
|
||||
);
|
||||
});
|
30
src/routes/users/sessions.ts
Normal file
30
src/routes/users/sessions.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Session, formatSession } from '@/db/models/Session';
|
||||
import { StatusError } from '@/services/error';
|
||||
import { handle } from '@/services/handler';
|
||||
import { makeRouter } from '@/services/router';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const userSessionsRouter = makeRouter((app) => {
|
||||
app.get(
|
||||
'/users/:uid/sessions',
|
||||
{
|
||||
schema: {
|
||||
params: z.object({
|
||||
uid: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handle(async ({ auth, params, em }) => {
|
||||
await auth.assert();
|
||||
|
||||
if (auth.user.id !== params.uid)
|
||||
throw new StatusError('Cannot modify user other than yourself', 403);
|
||||
|
||||
const sessions = await em.find(Session, {
|
||||
user: params.uid,
|
||||
});
|
||||
|
||||
return sessions.map(formatSession);
|
||||
}),
|
||||
);
|
||||
});
|
Reference in New Issue
Block a user