forked from LoginRadius/engineering-blog-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
239 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Application } from "https://deno.land/x/oak/mod.ts"; | ||
import router from "./src/routes/allRoutes.ts"; | ||
|
||
const app = new Application(); | ||
const PORT = 8080; | ||
|
||
app.use(router.routes()); | ||
app.use(router.allowedMethods()); | ||
|
||
console.log(`Application is listening on port: ${PORT}`); | ||
|
||
await app.listen({port:PORT}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import db from "../database/connectDB.ts"; | ||
import { TaskSchema } from "../schema/task.ts"; | ||
import {ObjectId} from "https://deno.land/x/[email protected]/mod.ts"; | ||
|
||
const tasks = db.collection<TaskSchema>("tasks"); | ||
|
||
export const create = async({request, response}:{request:any;response:any}) => { | ||
const {name, isCompleted} = await request.body().value; | ||
|
||
const _id = await tasks.insertOne({ | ||
name, | ||
isCompleted | ||
}); | ||
response.body = {message: "Task created!!", id:_id, name:name, Completed:isCompleted} | ||
}; | ||
|
||
export const getTasks = async ({response}:{response:any}) => { | ||
const allTasks = await tasks.find({}).toArray(); | ||
|
||
response.status = 200; | ||
response.body = {tasks:allTasks}; | ||
}; | ||
|
||
export const getById = async ({ | ||
params, | ||
response | ||
}:{ | ||
params:{taskId:string}; | ||
response:any; | ||
}) => { | ||
const taskId = params.taskId; | ||
const task = await tasks.findOne({_id:new ObjectId(taskId)}); | ||
|
||
if(!task){ | ||
response.body = {message: `no task with Id: ${taskId}`}; | ||
return; | ||
} | ||
response.status = 200; | ||
response.body = {task: task} | ||
}; | ||
|
||
export const updateById = async ({ | ||
params, | ||
request, | ||
response | ||
}:{ | ||
params:{taskId:string}; | ||
request:any; | ||
response:any; | ||
}) => { | ||
const taskId = params.taskId; | ||
const {name, isCompleted} = await request.body().value; | ||
const task = await tasks.updateOne({_id:new ObjectId(taskId)}, | ||
{$set:{name:name, isCompleted:isCompleted}}); | ||
|
||
response.status = 200; | ||
response.body = {message:"Updated task", task:task}; | ||
}; | ||
|
||
export const deleteTask = async ({ | ||
params, | ||
response, | ||
}:{ | ||
params:{taskId:string}; | ||
response:any; | ||
}) => { | ||
const taskId = params.taskId; | ||
const task = await tasks.deleteOne({_id:new ObjectId(taskId)}); | ||
response.status = 200; | ||
response.body = {message:"Deleted task", task:task}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import db from "../database/connectDB.ts"; | ||
import * as bcrypt from "https://deno.land/x/bcrypt/mod.ts"; | ||
import { UserSchema } from "../schema/user.ts"; | ||
import { create } from "https://deno.land/x/[email protected]/mod.ts"; | ||
import { key } from "../utils/apiKey.ts"; | ||
|
||
const Users = db.collection<UserSchema>("users"); | ||
|
||
//create a user | ||
export const signup = async({request, response}:{request:any;response:any}) => { | ||
const {username, password} = await request.body().value; | ||
const salt = await bcrypt.genSalt(8); | ||
const hashedPassword = await bcrypt.hash(password, salt); | ||
|
||
const _id = await Users.insertOne({ | ||
username, | ||
password:hashedPassword | ||
}); | ||
response.status =201; | ||
response.body = {message: "User created", userId:_id, user:username} | ||
}; | ||
|
||
//signin a user | ||
export const signin = async ({request, response}:{request:any; response:any}) => { | ||
|
||
const body = await request.body(); | ||
const {username, password} = await body.value; | ||
|
||
const user = await Users.findOne({username}); | ||
|
||
if(!user) { | ||
response.body = 404; | ||
response.body = {message: `user "${username}" not found`}; | ||
return; | ||
} | ||
const confirmPassword = await bcrypt.compare(password, user.password); | ||
if(!confirmPassword){ | ||
response.body = 404; | ||
response.body = {message: "Incorrect password"}; | ||
return; | ||
} | ||
|
||
//authenticate a user | ||
const payload = { | ||
id: user._id, | ||
name: username | ||
}; | ||
const jwt = await create({ alg: "HS512", typ: "JWT" }, { payload }, key); | ||
|
||
if(jwt) { | ||
response.status = 200; | ||
response.body = { | ||
userId: user._id, | ||
username: user.username, | ||
token: jwt, | ||
} | ||
} else { | ||
response.status = 500; | ||
response.body = { | ||
message: "internal server error" | ||
} | ||
} | ||
return; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { MongoClient } from "https://deno.land/x/[email protected]/mod.ts"; | ||
|
||
const client = new MongoClient(); | ||
|
||
// Connecting to a Mongo Atlas Database | ||
await client.connect({ | ||
db: 'deno_auth', | ||
tls: true, | ||
servers: [ | ||
{ | ||
host: "dbhost", | ||
port: 27017, | ||
}, | ||
], | ||
credential: { | ||
username: "dbName", | ||
password: "dbPassword", | ||
db: "admin", | ||
mechanism: "SCRAM-SHA-1", | ||
}, | ||
}); | ||
|
||
console.log("Database connected!"); | ||
const db = client.database("deno_auth"); | ||
|
||
export default db; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { verify } from "https://deno.land/x/[email protected]/mod.ts"; | ||
import { key } from "../utils/apiKey.ts"; | ||
import { Context } from "https://deno.land/x/oak/mod.ts"; | ||
|
||
export const authourized = async (ctx: Context, next:any) => { | ||
try{ | ||
const headers: Headers = ctx.request.headers; | ||
const authorization = headers.get('Authorization'); | ||
if(!authorization) { | ||
ctx.response.status = 401; | ||
return; | ||
} | ||
const jwt = authorization.split(' ')[1]; | ||
|
||
if(!jwt) { | ||
ctx.response.status = 401; | ||
return; | ||
} | ||
const payload = await verify(jwt, key); | ||
|
||
if(!payload){ | ||
throw new Error("!payload") | ||
} | ||
await next(); | ||
|
||
} catch (error) { | ||
ctx.response.status = 401; | ||
ctx.response.body ={message: "You are not authorized to access this route"} | ||
return; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Router } from "https://deno.land/x/oak/mod.ts"; | ||
import {signup, signin} from "../controllers/users.ts"; | ||
import {create, getTasks, getById, updateById, deleteTask} from "../controllers/tasks.ts"; | ||
import { authourized } from "../middlewares/isAuthorized.ts"; | ||
|
||
const router = new Router(); | ||
|
||
//User routes | ||
router.post("/api/signup", signup) | ||
.post("/api/signin", signin); | ||
|
||
//Task routes | ||
router.post("/api/tasks", authourized, create) | ||
.get("/api/tasks", authourized, getTasks) | ||
.get("/api/tasks/:taskId", authourized, getById) | ||
.patch("/api/tasks/:taskId", authourized, updateById) | ||
.delete("/api/tasks/:taskId", authourized, deleteTask); | ||
|
||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface TaskSchema { | ||
name: string; | ||
isCompleted: boolean; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import {ObjectId} from "https://deno.land/x/[email protected]/mod.ts"; | ||
|
||
export interface UserSchema { | ||
_id: ObjectId; | ||
username: string; | ||
password: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const key = await crypto.subtle.generateKey( | ||
{ name: "HMAC", hash: "SHA-512" }, | ||
true, | ||
["sign", "verify"], | ||
); |