Skip to content

Commit

Permalink
Merge pull request LoginRadius#213 from icode247/auth-with-deno
Browse files Browse the repository at this point in the history
added the sample code
  • Loading branch information
raghunath-r-a authored Jul 28, 2022
2 parents bab320c + 4e1abe1 commit 3f8747c
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Deno/denoAPI_JWT_Auth/app.ts
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});
71 changes: 71 additions & 0 deletions Deno/denoAPI_JWT_Auth/src/controllers/tasks.ts
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};
};
64 changes: 64 additions & 0 deletions Deno/denoAPI_JWT_Auth/src/controllers/users.ts
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;
}
7 changes: 7 additions & 0 deletions Deno/denoAPI_JWT_Auth/src/database/connectDB.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { MongoClient } from "https://deno.land/x/[email protected]/mod.ts";

const dbString = `DB_STRING`;
const client = new MongoClient();
await client.connect(dbString);
const db = client.database("deno_auth");
export default db;
31 changes: 31 additions & 0 deletions Deno/denoAPI_JWT_Auth/src/middlewares/isAuthorized.ts
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;
}
};
19 changes: 19 additions & 0 deletions Deno/denoAPI_JWT_Auth/src/routes/allRoutes.ts
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;
4 changes: 4 additions & 0 deletions Deno/denoAPI_JWT_Auth/src/schema/task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface TaskSchema {
name: string;
isCompleted: boolean;
}
7 changes: 7 additions & 0 deletions Deno/denoAPI_JWT_Auth/src/schema/user.ts
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;
}
5 changes: 5 additions & 0 deletions Deno/denoAPI_JWT_Auth/src/utils/apiKey.ts
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"],
);

0 comments on commit 3f8747c

Please sign in to comment.