소스 검색

Create route for creating a new user.

Lee Morgan 1 년 전
부모
커밋
420bcd75e9
8개의 변경된 파일131개의 추가작업 그리고 0개의 파일을 삭제
  1. 2 0
      app.js
  2. 62 0
      controllers/user.js
  3. 11 0
      documentation/bruno/User/Create.bru
  4. 9 0
      documentation/bruno/bruno.json
  5. 4 0
      models/User.js
  6. 35 0
      package-lock.json
  7. 1 0
      package.json
  8. 7 0
      routes/user.js

+ 2 - 0
app.js

@@ -8,6 +8,7 @@ import esbuild from "esbuild";
 import {catchError} from "./HttpError.js";
 
 import otherRoutes from "./routes/other.js";
+import userRoutes from "./routes/user.js";
 
 let mongoString = "mongodb://127.0.0.1/workout";
 if(process.env.COOKIE_SECRET){
@@ -34,6 +35,7 @@ app.use(cors({
 app.use(express.json());
 
 otherRoutes(app);
+userRoutes(app);
 
 app.use(catchError);
 

+ 62 - 0
controllers/user.js

@@ -0,0 +1,62 @@
+import User from "../models/User.js";
+
+import {HttpError} from "../HttpError.js";
+import bcrypt from "bcrypt";
+import crypto from "crypto";
+
+const createRoute = async (req, res, next)=>{
+    try{
+        const user = await createUser(req.body);
+        await user.save();
+        res.json(responseUser(user));
+    }catch(e){next(e)}
+}
+
+/*
+ Create a new User object
+ @param {Object} - Request body with user data
+ @return {User} - User object
+ */
+const createUser = async (data)=>{
+    return new User({
+        name: data.name,
+        email: data.email.toLowerCase(),
+        password: await hashPass(data.pass),
+        workouts: [],
+        uuid: createUuid()
+    });
+}
+
+/*
+ Hash a password
+ @param {String} - Password to hash
+ @return {String} - Hashed password
+ */
+const hashPass = async (password)=>{
+    return await bcrypt.hash(password, 10);
+}
+
+/*
+ Create user object for sending to frontend
+ @param {User} - User object
+ @return {User} - Modified User object
+ */
+const responseUser = (user)=>{
+    return {
+        name: user.name,
+        email: user.email,
+        workouts: user.workouts
+    };
+}
+
+/*
+ Create a new UUID token
+ @return {String} - UUID token
+ */
+const createUuid = ()=>{
+    return crypto.randomUUID();
+}
+
+export {
+    createRoute
+}

+ 11 - 0
documentation/bruno/User/Create.bru

@@ -0,0 +1,11 @@
+meta {
+  name: Create
+  type: http
+  seq: 1
+}
+
+post {
+  url: http://localhost:8000/user
+  body: none
+  auth: none
+}

+ 9 - 0
documentation/bruno/bruno.json

@@ -0,0 +1,9 @@
+{
+  "version": "1",
+  "name": "Workout Tracker",
+  "type": "collection",
+  "ignore": [
+    "node_modules",
+    ".git"
+  ]
+}

+ 4 - 0
models/User.js

@@ -1,6 +1,10 @@
 import mongoose from "mongoose";
 
 const UserSchema = mongoose.Schema({
+    name: {
+        type: String,
+        required: true
+    },
     email: {
         type: String,
         required: true

+ 35 - 0
package-lock.json

@@ -9,6 +9,7 @@
       "version": "1.0.0",
       "license": "ISC",
       "dependencies": {
+        "bcrypt": "^6.0.0",
         "compression": "^1.8.0",
         "cookie-parser": "^1.4.7",
         "cors": "^2.8.5",
@@ -454,6 +455,20 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/bcrypt": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz",
+      "integrity": "sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "dependencies": {
+        "node-addon-api": "^8.3.0",
+        "node-gyp-build": "^4.8.4"
+      },
+      "engines": {
+        "node": ">= 18"
+      }
+    },
     "node_modules/body-parser": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
@@ -1174,6 +1189,26 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/node-addon-api": {
+      "version": "8.3.1",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz",
+      "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==",
+      "license": "MIT",
+      "engines": {
+        "node": "^18 || ^20 || >= 21"
+      }
+    },
+    "node_modules/node-gyp-build": {
+      "version": "4.8.4",
+      "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+      "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+      "license": "MIT",
+      "bin": {
+        "node-gyp-build": "bin.js",
+        "node-gyp-build-optional": "optional.js",
+        "node-gyp-build-test": "build-test.js"
+      }
+    },
     "node_modules/object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",

+ 1 - 0
package.json

@@ -19,6 +19,7 @@
     "dev": "nodemon app.js --ignore views/build/ --ext js,css,html"
   },
   "dependencies": {
+    "bcrypt": "^6.0.0",
     "compression": "^1.8.0",
     "cookie-parser": "^1.4.7",
     "cors": "^2.8.5",

+ 7 - 0
routes/user.js

@@ -0,0 +1,7 @@
+import {
+    createRoute
+} from "../controllers/user.js";
+
+export default (app)=>{
+    app.post("/user", createRoute);
+}