Add services and auth
This commit is contained in:
parent
9b0b5dc040
commit
5dec454afb
46 changed files with 900 additions and 31 deletions
56
src/controllers/auth/auth.ts
Normal file
56
src/controllers/auth/auth.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import { type FastifyReply, type FastifyRequest } from "fastify";
|
||||
import type {
|
||||
ILoginRequest,
|
||||
IRegisterResponseError,
|
||||
IRegisterResponseSuccess,
|
||||
IRegisterRequest,
|
||||
ILoginResponseError,
|
||||
ILoginResponseSuccess,
|
||||
} from "./types.js";
|
||||
import { loginUser, registerUser } from "../../services/auth/auth.js";
|
||||
|
||||
const postRegister = async (request: FastifyRequest, _reply: FastifyReply) => {
|
||||
const { username, password, email } = request.body as IRegisterRequest;
|
||||
|
||||
const newUser = await registerUser({
|
||||
username: username,
|
||||
password: password,
|
||||
email: email,
|
||||
});
|
||||
|
||||
if (!newUser) {
|
||||
return {
|
||||
error: "user already exists",
|
||||
} as IRegisterResponseError;
|
||||
}
|
||||
|
||||
return {
|
||||
id: newUser.id,
|
||||
username: newUser.username,
|
||||
registerDate: newUser.registerDate?.getTime(),
|
||||
} as IRegisterResponseSuccess;
|
||||
};
|
||||
|
||||
const postLogin = async (request: FastifyRequest, _reply: FastifyReply) => {
|
||||
const { username, password } = request.body as ILoginRequest;
|
||||
|
||||
const session = await loginUser({
|
||||
username: username,
|
||||
password: password,
|
||||
});
|
||||
|
||||
if (!session) {
|
||||
return {
|
||||
ownerId: "",
|
||||
error: "incorrect credentials",
|
||||
} as ILoginResponseError;
|
||||
}
|
||||
|
||||
return {
|
||||
id: session.id,
|
||||
ownerId: session.userId,
|
||||
token: session.token,
|
||||
} as ILoginResponseSuccess;
|
||||
};
|
||||
|
||||
export { postRegister, postLogin };
|
||||
3
src/controllers/auth/index.ts
Normal file
3
src/controllers/auth/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./auth.js";
|
||||
export * from "./routes.js";
|
||||
export * from "./types.js";
|
||||
9
src/controllers/auth/routes.ts
Normal file
9
src/controllers/auth/routes.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { type FastifyInstance } from "fastify";
|
||||
import * as controller from "./auth.js";
|
||||
|
||||
const authRoutes = async (fastify: FastifyInstance) => {
|
||||
fastify.post(`/register`, controller.postRegister);
|
||||
fastify.post(`/login`, controller.postLogin);
|
||||
};
|
||||
|
||||
export { authRoutes };
|
||||
40
src/controllers/auth/types.ts
Normal file
40
src/controllers/auth/types.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
interface IRegisterRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
email?: string;
|
||||
}
|
||||
|
||||
interface IRegisterResponseSuccess {
|
||||
id: string;
|
||||
username: string;
|
||||
registerDate: number;
|
||||
}
|
||||
|
||||
interface IRegisterResponseError {
|
||||
error: string;
|
||||
}
|
||||
|
||||
interface ILoginRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface ILoginResponseSuccess {
|
||||
id: string;
|
||||
ownerId: string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
interface ILoginResponseError {
|
||||
ownerId: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
export {
|
||||
type IRegisterRequest,
|
||||
type IRegisterResponseSuccess,
|
||||
type IRegisterResponseError,
|
||||
type ILoginRequest,
|
||||
type ILoginResponseSuccess,
|
||||
type ILoginResponseError,
|
||||
};
|
||||
27
src/controllers/channel/channel.ts
Normal file
27
src/controllers/channel/channel.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { type FastifyReply, type FastifyRequest } from "fastify";
|
||||
import type {
|
||||
IChannelParams,
|
||||
IChannelResponseError,
|
||||
IChannelResponseSuccess,
|
||||
} from "./types.js";
|
||||
import { getChannelById } from "../../services/channel/channel.js";
|
||||
|
||||
const getChannel = async (request: FastifyRequest, _reply: FastifyReply) => {
|
||||
const { id } = request.params as IChannelParams;
|
||||
|
||||
const channel = await getChannelById(id);
|
||||
if (!channel) {
|
||||
return {
|
||||
id: id,
|
||||
error: "channel does not exist",
|
||||
} as IChannelResponseError;
|
||||
}
|
||||
|
||||
return {
|
||||
id: channel.id,
|
||||
name: channel.name,
|
||||
communityId: channel.communityId,
|
||||
} as IChannelResponseSuccess;
|
||||
};
|
||||
|
||||
export { getChannel };
|
||||
3
src/controllers/channel/index.ts
Normal file
3
src/controllers/channel/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./channel.js";
|
||||
export * from "./routes.js";
|
||||
export * from "./types.js";
|
||||
8
src/controllers/channel/routes.ts
Normal file
8
src/controllers/channel/routes.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { type FastifyInstance } from "fastify";
|
||||
import * as controller from "./channel.js";
|
||||
|
||||
const channelRoutes = async (fastify: FastifyInstance) => {
|
||||
fastify.get(`/:id`, controller.getChannel);
|
||||
};
|
||||
|
||||
export { channelRoutes };
|
||||
20
src/controllers/channel/types.ts
Normal file
20
src/controllers/channel/types.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
interface IChannelParams {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface IChannelResponseError {
|
||||
id: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
interface IChannelResponseSuccess {
|
||||
id: string;
|
||||
name: string;
|
||||
communityId: string;
|
||||
}
|
||||
|
||||
export {
|
||||
type IChannelParams,
|
||||
type IChannelResponseError,
|
||||
type IChannelResponseSuccess,
|
||||
};
|
||||
27
src/controllers/community/community.ts
Normal file
27
src/controllers/community/community.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { type FastifyReply, type FastifyRequest } from "fastify";
|
||||
import type {
|
||||
ICommunityParams,
|
||||
ICommunityResponseError,
|
||||
ICommunityResponseSuccess,
|
||||
} from "./types.js";
|
||||
import { getCommunityById } from "../../services/community/community.js";
|
||||
|
||||
const getCommunity = async (request: FastifyRequest, _reply: FastifyReply) => {
|
||||
const { id } = request.params as ICommunityParams;
|
||||
|
||||
const community = await getCommunityById(id);
|
||||
if (!community) {
|
||||
return {
|
||||
id: id,
|
||||
error: "community does not exist",
|
||||
} as ICommunityResponseError;
|
||||
}
|
||||
|
||||
return {
|
||||
id: community.id,
|
||||
name: community.name,
|
||||
description: community.description,
|
||||
} as ICommunityResponseSuccess;
|
||||
};
|
||||
|
||||
export { getCommunity };
|
||||
3
src/controllers/community/index.ts
Normal file
3
src/controllers/community/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./community.js";
|
||||
export * from "./routes.js";
|
||||
export * from "./types.js";
|
||||
8
src/controllers/community/routes.ts
Normal file
8
src/controllers/community/routes.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { type FastifyInstance } from "fastify";
|
||||
import * as controller from "./community.js";
|
||||
|
||||
const communityRoutes = async (fastify: FastifyInstance) => {
|
||||
fastify.get(`/:id`, controller.getCommunity);
|
||||
};
|
||||
|
||||
export { communityRoutes };
|
||||
20
src/controllers/community/types.ts
Normal file
20
src/controllers/community/types.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
interface ICommunityParams {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface ICommunityResponseError {
|
||||
id: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
interface ICommunityResponseSuccess {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export {
|
||||
type ICommunityParams,
|
||||
type ICommunityResponseError,
|
||||
type ICommunityResponseSuccess,
|
||||
};
|
||||
3
src/controllers/role/index.ts
Normal file
3
src/controllers/role/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./role.js";
|
||||
export * from "./routes.js";
|
||||
export * from "./types.js";
|
||||
27
src/controllers/role/role.ts
Normal file
27
src/controllers/role/role.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { type FastifyReply, type FastifyRequest } from "fastify";
|
||||
import type {
|
||||
IRoleParams,
|
||||
IRoleResponseError,
|
||||
IRoleResponseSuccess,
|
||||
} from "./types.js";
|
||||
import { getRoleById } from "../../services/role/role.js";
|
||||
|
||||
const getRole = async (request: FastifyRequest, _reply: FastifyReply) => {
|
||||
const { id } = request.params as IRoleParams;
|
||||
|
||||
const role = await getRoleById(id);
|
||||
if (!role) {
|
||||
return {
|
||||
id: id,
|
||||
error: "role does not exist",
|
||||
} as IRoleResponseError;
|
||||
}
|
||||
|
||||
return {
|
||||
id: role.id,
|
||||
name: role.name,
|
||||
communityId: role.communityId,
|
||||
} as IRoleResponseSuccess;
|
||||
};
|
||||
|
||||
export { getRole };
|
||||
8
src/controllers/role/routes.ts
Normal file
8
src/controllers/role/routes.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { type FastifyInstance } from "fastify";
|
||||
import * as controller from "./role.js";
|
||||
|
||||
const roleRoutes = async (fastify: FastifyInstance) => {
|
||||
fastify.get(`/:id`, controller.getRole);
|
||||
};
|
||||
|
||||
export { roleRoutes };
|
||||
16
src/controllers/role/types.ts
Normal file
16
src/controllers/role/types.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
interface IRoleParams {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface IRoleResponseError {
|
||||
id: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
interface IRoleResponseSuccess {
|
||||
id: string;
|
||||
name: string;
|
||||
communityId: string;
|
||||
}
|
||||
|
||||
export { type IRoleParams, type IRoleResponseError, type IRoleResponseSuccess };
|
||||
3
src/controllers/session/index.ts
Normal file
3
src/controllers/session/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./session.js";
|
||||
export * from "./routes.js";
|
||||
export * from "./types.js";
|
||||
8
src/controllers/session/routes.ts
Normal file
8
src/controllers/session/routes.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { type FastifyInstance } from "fastify";
|
||||
import * as controller from "./session.js";
|
||||
|
||||
const sessionRoutes = async (fastify: FastifyInstance) => {
|
||||
fastify.get(`/:id`, controller.getSession);
|
||||
};
|
||||
|
||||
export { sessionRoutes };
|
||||
26
src/controllers/session/session.ts
Normal file
26
src/controllers/session/session.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { type FastifyReply, type FastifyRequest } from "fastify";
|
||||
import type {
|
||||
ISessionParams,
|
||||
ISessionResponseError,
|
||||
ISessionResponseSuccess,
|
||||
} from "./types.js";
|
||||
import { getSessionById } from "../../services/session/session.js";
|
||||
|
||||
const getSession = async (request: FastifyRequest, _reply: FastifyReply) => {
|
||||
const { id } = request.params as ISessionParams;
|
||||
|
||||
const session = await getSessionById(id);
|
||||
if (!session) {
|
||||
return {
|
||||
id: id,
|
||||
error: "session does not exist",
|
||||
} as ISessionResponseError;
|
||||
}
|
||||
|
||||
return {
|
||||
id: session.id,
|
||||
userId: session.userId,
|
||||
} as ISessionResponseSuccess;
|
||||
};
|
||||
|
||||
export { getSession };
|
||||
19
src/controllers/session/types.ts
Normal file
19
src/controllers/session/types.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
interface ISessionParams {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface ISessionResponseError {
|
||||
id: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
interface ISessionResponseSuccess {
|
||||
id: string;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
export {
|
||||
type ISessionParams,
|
||||
type ISessionResponseError,
|
||||
type ISessionResponseSuccess,
|
||||
};
|
||||
|
|
@ -2,7 +2,8 @@ import { type FastifyInstance } from "fastify";
|
|||
import * as controller from "./test.js";
|
||||
|
||||
const testRoutes = async (fastify: FastifyInstance) => {
|
||||
fastify.get("/test", controller.test);
|
||||
fastify.get("/ping", controller.getPing);
|
||||
fastify.get("/test", controller.getTest);
|
||||
};
|
||||
|
||||
export { testRoutes };
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { type FastifyReply, type FastifyRequest } from "fastify";
|
||||
import { testdb } from "../../store/store.js";
|
||||
|
||||
const test = async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
testdb();
|
||||
|
||||
return [{ name: "Alice" }];
|
||||
const getPing = async (_request: FastifyRequest, _reply: FastifyReply) => {
|
||||
return [{ message: "pong" }];
|
||||
};
|
||||
|
||||
export { test };
|
||||
const getTest = async (_request: FastifyRequest, _reply: FastifyReply) => {
|
||||
return [{ message: "ok" }];
|
||||
};
|
||||
|
||||
export { getPing, getTest };
|
||||
|
|
|
|||
3
src/controllers/user/index.ts
Normal file
3
src/controllers/user/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from "./user.js";
|
||||
export * from "./routes.js";
|
||||
export * from "./types.js";
|
||||
9
src/controllers/user/routes.ts
Normal file
9
src/controllers/user/routes.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import { type FastifyInstance } from "fastify";
|
||||
import * as controller from "./user.js";
|
||||
|
||||
const userRoutes = async (fastify: FastifyInstance) => {
|
||||
fastify.get(`/:id`, controller.getUser);
|
||||
fastify.get(`/:id/sessions`, controller.getSessions);
|
||||
};
|
||||
|
||||
export { userRoutes };
|
||||
41
src/controllers/user/types.ts
Normal file
41
src/controllers/user/types.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
interface IUserParams {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface IUserResponseError {
|
||||
id: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
interface IUserResponseSuccess {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
description: string;
|
||||
admin: boolean;
|
||||
registerDate: number;
|
||||
lastLogin: number;
|
||||
}
|
||||
|
||||
interface ISessionsResponseError {
|
||||
id: string;
|
||||
error: string;
|
||||
}
|
||||
|
||||
interface ISessionsResponseSuccess {
|
||||
sessions: ISessionsResponseSession[];
|
||||
}
|
||||
|
||||
interface ISessionsResponseSession {
|
||||
id: string;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
export {
|
||||
type IUserParams,
|
||||
type IUserResponseError,
|
||||
type IUserResponseSuccess,
|
||||
type ISessionsResponseError,
|
||||
type ISessionsResponseSuccess,
|
||||
type ISessionsResponseSession,
|
||||
};
|
||||
53
src/controllers/user/user.ts
Normal file
53
src/controllers/user/user.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { type FastifyReply, type FastifyRequest } from "fastify";
|
||||
import type {
|
||||
IUserParams,
|
||||
IUserResponseError,
|
||||
IUserResponseSuccess,
|
||||
ISessionsResponseError,
|
||||
ISessionsResponseSuccess,
|
||||
} from "./types.js";
|
||||
import { getUserById, getUserSessionsById } from "../../services/user/user.js";
|
||||
|
||||
const getUser = async (request: FastifyRequest, _reply: FastifyReply) => {
|
||||
const { id } = request.params as IUserParams;
|
||||
|
||||
const user = await getUserById(id);
|
||||
if (!user) {
|
||||
return {
|
||||
id: id,
|
||||
error: "user does not exist",
|
||||
} as IUserResponseError;
|
||||
}
|
||||
|
||||
return {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
description: user.description,
|
||||
admin: user.admin,
|
||||
registerDate: user.registerDate.getTime(),
|
||||
lastLogin: user.lastLogin?.getTime() ?? 0,
|
||||
} as IUserResponseSuccess;
|
||||
};
|
||||
|
||||
const getSessions = async (request: FastifyRequest, _reply: FastifyReply) => {
|
||||
const { id } = request.params as IUserParams;
|
||||
const authHeader = request.headers["authorization"];
|
||||
|
||||
const sessions = await getUserSessionsById(id, authHeader);
|
||||
if (!sessions) {
|
||||
return {
|
||||
id: id,
|
||||
error: "user does not exist or you have no access",
|
||||
} as ISessionsResponseError;
|
||||
}
|
||||
|
||||
return {
|
||||
sessions: sessions.map((session) => ({
|
||||
id: session.id,
|
||||
userId: session.userId,
|
||||
})),
|
||||
} as ISessionsResponseSuccess;
|
||||
};
|
||||
|
||||
export { getUser, getSessions };
|
||||
59
src/helpers.ts
Normal file
59
src/helpers.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import jwt from "jsonwebtoken";
|
||||
import type { Session, User } from "./generated/prisma/client.js";
|
||||
import { getDB } from "./store/store.js";
|
||||
|
||||
const getJwtSecret = () => {
|
||||
return process.env.JWT_SECRET || "";
|
||||
};
|
||||
|
||||
const verifyToken = (token: string): string | jwt.JwtPayload | null => {
|
||||
try {
|
||||
return jwt.verify(token, getJwtSecret());
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const getSessionFromToken = async (token: string): Promise<Session | null> => {
|
||||
return await getDB().session.findFirst({
|
||||
where: {
|
||||
token: token,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const getUserFromToken = async (token: string): Promise<User | null> => {
|
||||
const session = await getSessionFromToken(token);
|
||||
|
||||
return await getDB().user.findFirst({
|
||||
where: {
|
||||
id: session?.userId ?? "invalid",
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const getUserFromAuth = async (
|
||||
authHeader: string | undefined,
|
||||
): Promise<User | null> => {
|
||||
const token = authHeader?.replace("Bearer ", "");
|
||||
|
||||
const verified = verifyToken(token ?? "") !== null;
|
||||
if (!verified || !token) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const user = await getUserFromToken(token);
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
export {
|
||||
getJwtSecret,
|
||||
verifyToken,
|
||||
getSessionFromToken,
|
||||
getUserFromToken,
|
||||
getUserFromAuth,
|
||||
};
|
||||
12
src/index.ts
12
src/index.ts
|
|
@ -2,12 +2,24 @@ import { config } from "./config.js";
|
|||
|
||||
import Fastify from "fastify";
|
||||
import { testRoutes } from "./controllers/test/routes.js";
|
||||
import { authRoutes } from "./controllers/auth/routes.js";
|
||||
import { userRoutes } from "./controllers/user/routes.js";
|
||||
import { sessionRoutes } from "./controllers/session/routes.js";
|
||||
import { communityRoutes } from "./controllers/community/routes.js";
|
||||
import { channelRoutes } from "./controllers/channel/routes.js";
|
||||
import { roleRoutes } from "./controllers/role/routes.js";
|
||||
|
||||
const app = Fastify({
|
||||
logger: true,
|
||||
});
|
||||
|
||||
app.register(testRoutes);
|
||||
app.register(authRoutes, { prefix: "/api/v1/auth" });
|
||||
app.register(userRoutes, { prefix: "/api/v1/user" });
|
||||
app.register(sessionRoutes, { prefix: "/api/v1/session" });
|
||||
app.register(communityRoutes, { prefix: "/api/v1/community" });
|
||||
app.register(channelRoutes, { prefix: "/api/v1/channel" });
|
||||
app.register(roleRoutes, { prefix: "/api/v1/role" });
|
||||
|
||||
app.listen({ port: config.port }, (err, address) => {
|
||||
if (err) throw err;
|
||||
|
|
|
|||
72
src/services/auth/auth.ts
Normal file
72
src/services/auth/auth.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import argon2 from "argon2";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import type { User, Session } from "../../generated/prisma/client.js";
|
||||
import { getDB } from "../../store/store.js";
|
||||
import type { IUserLogin, IUserRegistration } from "./types.js";
|
||||
import { getJwtSecret } from "../../helpers.js";
|
||||
|
||||
const registerUser = async (
|
||||
registration: IUserRegistration,
|
||||
): Promise<User | null> => {
|
||||
const existingUser = await getDB().user.findUnique({
|
||||
where: { username: registration.username },
|
||||
});
|
||||
if (existingUser) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const passwordHash = await hashPassword(registration.password);
|
||||
|
||||
let newUser: User | null = null;
|
||||
try {
|
||||
newUser = await getDB().user.create({
|
||||
data: {
|
||||
username: registration.username,
|
||||
passwordHash: passwordHash,
|
||||
email: registration.email ?? null,
|
||||
},
|
||||
});
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
return newUser;
|
||||
};
|
||||
|
||||
const loginUser = async (login: IUserLogin): Promise<Session | null> => {
|
||||
const user = await getDB().user.findUnique({
|
||||
where: { username: login.username },
|
||||
});
|
||||
|
||||
const passwordCorrect = await argon2.verify(
|
||||
user?.passwordHash ?? "",
|
||||
login.password,
|
||||
);
|
||||
|
||||
if (!user || !passwordCorrect) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await getDB().session.create({
|
||||
data: {
|
||||
token: createToken(user.id),
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const hashPassword = async (password: string): Promise<string> => {
|
||||
return await argon2.hash(password, {
|
||||
type: argon2.argon2id,
|
||||
memoryCost: 2 ** 16,
|
||||
timeCost: 4,
|
||||
parallelism: 1,
|
||||
});
|
||||
};
|
||||
|
||||
const createToken = (userId: string) => {
|
||||
return jwt.sign({ sub: userId }, getJwtSecret());
|
||||
};
|
||||
|
||||
export { registerUser, loginUser, hashPassword };
|
||||
2
src/services/auth/index.ts
Normal file
2
src/services/auth/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./auth.js";
|
||||
export * from "./types.js";
|
||||
12
src/services/auth/types.ts
Normal file
12
src/services/auth/types.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
interface IUserRegistration {
|
||||
username: string;
|
||||
password: string;
|
||||
email?: string | undefined;
|
||||
}
|
||||
|
||||
interface IUserLogin {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export { type IUserRegistration, type IUserLogin };
|
||||
10
src/services/channel/channel.ts
Normal file
10
src/services/channel/channel.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { Channel } from "../../generated/prisma/client.js";
|
||||
import { getDB } from "../../store/store.js";
|
||||
|
||||
const getChannelById = async (id: string): Promise<Channel | null> => {
|
||||
return await getDB().channel.findUnique({
|
||||
where: { id: id },
|
||||
});
|
||||
};
|
||||
|
||||
export { getChannelById };
|
||||
1
src/services/channel/index.ts
Normal file
1
src/services/channel/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./channel.js";
|
||||
10
src/services/community/community.ts
Normal file
10
src/services/community/community.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { Community } from "../../generated/prisma/client.js";
|
||||
import { getDB } from "../../store/store.js";
|
||||
|
||||
const getCommunityById = async (id: string): Promise<Community | null> => {
|
||||
return await getDB().community.findUnique({
|
||||
where: { id: id },
|
||||
});
|
||||
};
|
||||
|
||||
export { getCommunityById };
|
||||
1
src/services/community/index.ts
Normal file
1
src/services/community/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./community.js";
|
||||
1
src/services/role/index.ts
Normal file
1
src/services/role/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./role.js";
|
||||
10
src/services/role/role.ts
Normal file
10
src/services/role/role.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { Role } from "../../generated/prisma/client.js";
|
||||
import { getDB } from "../../store/store.js";
|
||||
|
||||
const getRoleById = async (id: string): Promise<Role | null> => {
|
||||
return await getDB().role.findUnique({
|
||||
where: { id: id },
|
||||
});
|
||||
};
|
||||
|
||||
export { getRoleById };
|
||||
1
src/services/session/index.ts
Normal file
1
src/services/session/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./session.js";
|
||||
10
src/services/session/session.ts
Normal file
10
src/services/session/session.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { Session } from "../../generated/prisma/client.js";
|
||||
import { getDB } from "../../store/store.js";
|
||||
|
||||
const getSessionById = async (id: string): Promise<Session | null> => {
|
||||
return await getDB().session.findUnique({
|
||||
where: { id: id },
|
||||
});
|
||||
};
|
||||
|
||||
export { getSessionById };
|
||||
1
src/services/user/index.ts
Normal file
1
src/services/user/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./user.js";
|
||||
27
src/services/user/user.ts
Normal file
27
src/services/user/user.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import type { User, Session } from "../../generated/prisma/client.js";
|
||||
import { getUserFromAuth } from "../../helpers.js";
|
||||
import { getDB } from "../../store/store.js";
|
||||
|
||||
const getUserById = async (id: string): Promise<User | null> => {
|
||||
return await getDB().user.findUnique({
|
||||
where: { id: id },
|
||||
});
|
||||
};
|
||||
|
||||
const getUserSessionsById = async (
|
||||
id: string,
|
||||
authHeader: string | undefined,
|
||||
): Promise<Session[] | null> => {
|
||||
const user = await getUserFromAuth(authHeader);
|
||||
if (!user || user.id !== id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await getDB().session.findMany({
|
||||
where: {
|
||||
userId: id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export { getUserById, getUserSessionsById };
|
||||
|
|
@ -1,2 +1 @@
|
|||
export * from "./store.js";
|
||||
export * from "./types.js";
|
||||
|
|
|
|||
|
|
@ -10,18 +10,8 @@ const adapter = new PrismaPg(pool);
|
|||
|
||||
const prisma = new PrismaClient({ adapter });
|
||||
|
||||
async function testdb() {
|
||||
const test = await prisma.user.findMany();
|
||||
/*
|
||||
const user = await prisma.user.create({
|
||||
data: { name: "Alice", email: `alice${Math.random()}@example.com` },
|
||||
});
|
||||
const getDB = (): PrismaClient => {
|
||||
return prisma;
|
||||
};
|
||||
|
||||
console.log("Created user:", user);
|
||||
|
||||
const test = await prisma.user.findMany();
|
||||
console.log(test);
|
||||
*/
|
||||
}
|
||||
|
||||
export { testdb };
|
||||
export { getDB };
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
interface IState {}
|
||||
|
||||
export { type IState };
|
||||
Loading…
Add table
Add a link
Reference in a new issue