Created new userRouter
modified: package.json modified: src/server/api/root.ts modified: src/server/api/routers/login.ts new file: src/server/api/routers/user.ts
This commit is contained in:
@ -17,8 +17,8 @@
|
|||||||
"@trpc/react-query": "^10.37.1",
|
"@trpc/react-query": "^10.37.1",
|
||||||
"@trpc/server": "^10.37.1",
|
"@trpc/server": "^10.37.1",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"framer-motion": "^10.16.4",
|
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
|
"framer-motion": "^10.16.4",
|
||||||
"mongoose": "^7.5.3",
|
"mongoose": "^7.5.3",
|
||||||
"next": "^13.4.19",
|
"next": "^13.4.19",
|
||||||
"next-auth": "^4.23.0",
|
"next-auth": "^4.23.0",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { exampleRouter } from "~/server/api/routers/example";
|
import { exampleRouter } from "~/server/api/routers/example";
|
||||||
import { createTRPCRouter } from "~/server/api/trpc";
|
import { createTRPCRouter } from "~/server/api/trpc";
|
||||||
import { loginRouter } from "./routers/login";
|
import { loginRouter } from "./routers/login";
|
||||||
|
import { userRouter } from "./routers/user";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the primary router for your server.
|
* This is the primary router for your server.
|
||||||
@ -10,6 +11,7 @@ import { loginRouter } from "./routers/login";
|
|||||||
export const appRouter = createTRPCRouter({
|
export const appRouter = createTRPCRouter({
|
||||||
example: exampleRouter,
|
example: exampleRouter,
|
||||||
login: loginRouter,
|
login: loginRouter,
|
||||||
|
user: userRouter,
|
||||||
});
|
});
|
||||||
|
|
||||||
// export type definition of API
|
// export type definition of API
|
||||||
|
@ -48,8 +48,7 @@ export const loginRouter = createTRPCRouter({
|
|||||||
login: publicProcedure
|
login: publicProcedure
|
||||||
.input(z.object({ username: z.string(), password: z.string()}))
|
.input(z.object({ username: z.string(), password: z.string()}))
|
||||||
.query(async ({ ctx, input }) => {
|
.query(async ({ ctx, input }) => {
|
||||||
// Encryption using bcrypt salt and pepper hashing
|
|
||||||
const saltRounds = 10;
|
|
||||||
// Get hash from database
|
// Get hash from database
|
||||||
const user = await ctx.UserModel.findOne({username: input.username});
|
const user = await ctx.UserModel.findOne({username: input.username});
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@ -58,6 +57,7 @@ export const loginRouter = createTRPCRouter({
|
|||||||
message: "User doesn't exist",
|
message: "User doesn't exist",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPasswordValid = await bcrypt.compare(input.password, user.password);
|
const isPasswordValid = await bcrypt.compare(input.password, user.password);
|
||||||
if (!isPasswordValid) {
|
if (!isPasswordValid) {
|
||||||
throw new TRPCError ({
|
throw new TRPCError ({
|
||||||
|
114
src/server/api/routers/user.ts
Normal file
114
src/server/api/routers/user.ts
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
import bcrypt from "bcrypt";
|
||||||
|
|
||||||
|
import {
|
||||||
|
createTRPCRouter,
|
||||||
|
protectedProcedure,
|
||||||
|
publicProcedure,
|
||||||
|
} from "~/server/api/trpc";
|
||||||
|
import { TRPCError } from "@trpc/server";
|
||||||
|
|
||||||
|
|
||||||
|
// Main login router for backend
|
||||||
|
export const userRouter = createTRPCRouter({
|
||||||
|
|
||||||
|
// Function to add a Api Key to a user
|
||||||
|
addUserApiKey: protectedProcedure
|
||||||
|
.input(z.object({username: z.string(), apiKey: z.object({name: z.string(), key: z.string(), iv: z.string()}) }))
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const user = await ctx.UserModel.findOne({username: input.username});
|
||||||
|
|
||||||
|
// Check if user exists
|
||||||
|
if (!user) {
|
||||||
|
throw new TRPCError ({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "User not found",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new API key to the user's array
|
||||||
|
user.apiKeys.push(input.apiKey);
|
||||||
|
|
||||||
|
// Save new user
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
// Return greeting information
|
||||||
|
return {
|
||||||
|
user_info: user
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Function to get a users Api Keys
|
||||||
|
getUserApiKeys: protectedProcedure
|
||||||
|
.input(z.object({ username: z.string()}))
|
||||||
|
.query(async ({ ctx, input }) => {
|
||||||
|
const user = await ctx.UserModel.findOne({username: input.username});
|
||||||
|
|
||||||
|
// Check if user exists
|
||||||
|
if (!user) {
|
||||||
|
throw new TRPCError ({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "User doesn't exist",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user has API keys
|
||||||
|
if (!user.apiKeys || user.apiKeys.length === 0) {
|
||||||
|
throw new TRPCError ({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "User has no api keys",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a list of the users API keys
|
||||||
|
return user.apiKeys
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Function to change a users password
|
||||||
|
changeUserPass: protectedProcedure
|
||||||
|
.input(z.object({username: z.string(), oldPass: z.string(), newPass: z.string(), newConfirm: z.string()}))
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const user = await ctx.UserModel.findOne({username: input.username});
|
||||||
|
|
||||||
|
// Check if user exists
|
||||||
|
if (!user) {
|
||||||
|
throw new TRPCError ({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "User not found",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check password validity
|
||||||
|
const isPasswordValid = await bcrypt.compare(input.oldPass, user.password);
|
||||||
|
if (!isPasswordValid) {
|
||||||
|
throw new TRPCError ({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "Username or Password is incorrect",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check new passwords
|
||||||
|
if (input.newPass != input.newConfirm) {
|
||||||
|
throw new TRPCError ({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: "New passwords do not match",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const saltRounds = 10;
|
||||||
|
const hashedPassword: string = await bcrypt.hash(input.newPass, saltRounds);
|
||||||
|
|
||||||
|
// Update password
|
||||||
|
user.password = hashedPassword
|
||||||
|
|
||||||
|
// Save new user information
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
// Return updated information
|
||||||
|
return {
|
||||||
|
user_info: user
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
});
|
Reference in New Issue
Block a user