From f50a01fc1c14d77d996e1822ac9ea11cf7e844a0 Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Tue, 23 Jun 2020 09:43:14 +0000 Subject: [PATCH 01/10] Added session example. --- examples/nodejs/session/app-session/index.ts | 25 ++++++++ examples/nodejs/session/app-session/store.ts | 62 +++++++++++++++++++ examples/nodejs/session/index.ts | 63 ++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 examples/nodejs/session/app-session/index.ts create mode 100644 examples/nodejs/session/app-session/store.ts create mode 100644 examples/nodejs/session/index.ts diff --git a/examples/nodejs/session/app-session/index.ts b/examples/nodejs/session/app-session/index.ts new file mode 100644 index 0000000..bac662c --- /dev/null +++ b/examples/nodejs/session/app-session/index.ts @@ -0,0 +1,25 @@ +import { Context } from "../context"; +import { Store } from "./store"; + +export class AppSession { + sessionid?: string | null; + store?: any; + + constructor() { + this.store = new Store(); + } + + public load(sessionid: string): any { + return this.sessionid? Object.assign(this.store.get(sessionid), {id: sessionid}) : null + } + + public create(sessionid: string, session: any) { + this.sessionid = sessionid + this.store.set(sessionid, session) + } + + public clear(sessionid: string) { + this.sessionid = null + this.store.destroy(sessionid) + } +} \ No newline at end of file diff --git a/examples/nodejs/session/app-session/store.ts b/examples/nodejs/session/app-session/store.ts new file mode 100644 index 0000000..b6d6432 --- /dev/null +++ b/examples/nodejs/session/app-session/store.ts @@ -0,0 +1,62 @@ +export class Store { + sessions: { [key: string]: any } + + constructor( + sessions: { [key: string]: any } = Object.create(null) + ) { + this.sessions = Object.create(null) + } + + public getSession(sessionId: string) { + var sess = this.sessions[sessionId] + + if (!sess) { + return + } + + // parse + sess = JSON.parse(sess) + + if (sess.cookie) { + var expires = typeof sess.cookie.expires === 'string' + ? new Date(sess.cookie.expires) + : sess.cookie.expires + + // destroy expired session + if (expires && expires <= Date.now()) { + delete this.sessions[sessionId] + return + } + } + + return sess + } + + public all() { + var sessionIds = Object.keys(this.sessions) + var sessions = Object.create(null) + + for (var i = 0; i < sessionIds.length; i++) { + var sessionId = sessionIds[i] + var session = this.getSession(sessionId) + + if (session) { + sessions[sessionId] = session; + } + } + + return sessions + } + + public set(sessionId: string, session: any) { + this.sessions[sessionId] = JSON.stringify(session) + } + + public get(sessionId: string) { + return this.getSession(sessionId) + } + + public destroy(sessionId: string) { + delete this.sessions[sessionId] + } +} \ No newline at end of file diff --git a/examples/nodejs/session/index.ts b/examples/nodejs/session/index.ts new file mode 100644 index 0000000..714a0e6 --- /dev/null +++ b/examples/nodejs/session/index.ts @@ -0,0 +1,63 @@ +import { Node } from "./node" +import { AppSession } from "./app-session" +import { randomBytes } from "tweetnacl"; + +const session = new AppSession(); +const users = [ + { + id: "john", + password: "123" + }, + { + id: "mary", + password: "456" + } +] + +const authenticate = (id: string, password: string) => { + var idx = users.findIndex(u => u.id === id) + return idx !== -1? users[idx] : -1 +} + +const main = async () => { + const node = await Node.start({ + addrs: [`127.0.0.1:9000`], + services: { + login: (ctx) => { + if (ctx.headers["params.id"] && ctx.headers["params.password"]) { + const authenticated = authenticate(ctx.headers["params.id"], ctx.headers["params.password"]); + if (authenticated !== -1) { + const sid = Buffer.from(randomBytes(32)).toString('hex'); + session.create(sid, authenticated); + ctx.json(session.load(sid)); + } + else { + ctx.json({ + err: "Invalid credentials" + }); + } + } + else { + ctx.json({ + err: "Invalid credentials" + }); + } + }, + signup: (ctx) => { + if (ctx.headers["params.id"] && ctx.headers["params.password"]) { + users.push({ + id: ctx.headers["params.id"], + password: ctx.headers["params.password"] + }) + ctx.send('done'); + } + }, + logout: (ctx) => { + const sess = session.load(ctx.headers["params.sid"]) + session.clear(sess.id) + } + }, + }); +}; + +main().catch((err) => console.error(err)); From 146d8ea46c34a6f5911e6251e42f1f7a6011b963 Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Tue, 23 Jun 2020 09:47:49 +0000 Subject: [PATCH 02/10] Modify naming. Minor fix to user.find. --- examples/nodejs/{session => basic_auth}/app-session/index.ts | 0 examples/nodejs/{session => basic_auth}/app-session/store.ts | 0 examples/nodejs/{session => basic_auth}/index.ts | 5 ++--- 3 files changed, 2 insertions(+), 3 deletions(-) rename examples/nodejs/{session => basic_auth}/app-session/index.ts (100%) rename examples/nodejs/{session => basic_auth}/app-session/store.ts (100%) rename examples/nodejs/{session => basic_auth}/index.ts (92%) diff --git a/examples/nodejs/session/app-session/index.ts b/examples/nodejs/basic_auth/app-session/index.ts similarity index 100% rename from examples/nodejs/session/app-session/index.ts rename to examples/nodejs/basic_auth/app-session/index.ts diff --git a/examples/nodejs/session/app-session/store.ts b/examples/nodejs/basic_auth/app-session/store.ts similarity index 100% rename from examples/nodejs/session/app-session/store.ts rename to examples/nodejs/basic_auth/app-session/store.ts diff --git a/examples/nodejs/session/index.ts b/examples/nodejs/basic_auth/index.ts similarity index 92% rename from examples/nodejs/session/index.ts rename to examples/nodejs/basic_auth/index.ts index 714a0e6..906dbfc 100644 --- a/examples/nodejs/session/index.ts +++ b/examples/nodejs/basic_auth/index.ts @@ -15,8 +15,7 @@ const users = [ ] const authenticate = (id: string, password: string) => { - var idx = users.findIndex(u => u.id === id) - return idx !== -1? users[idx] : -1 + return users.find(u => u.id === id) } const main = async () => { @@ -26,7 +25,7 @@ const main = async () => { login: (ctx) => { if (ctx.headers["params.id"] && ctx.headers["params.password"]) { const authenticated = authenticate(ctx.headers["params.id"], ctx.headers["params.password"]); - if (authenticated !== -1) { + if (authenticated) { const sid = Buffer.from(randomBytes(32)).toString('hex'); session.create(sid, authenticated); ctx.json(session.load(sid)); From 744a8e0c8e83cd24028edb6722b94c62134b1acf Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Tue, 23 Jun 2020 09:50:55 +0000 Subject: [PATCH 03/10] Rename AppSession to MemorySessionStore. --- examples/nodejs/basic_auth/index.ts | 2 +- .../basic_auth/{app-session => memory-session-store}/index.ts | 2 +- .../basic_auth/{app-session => memory-session-store}/store.ts | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename examples/nodejs/basic_auth/{app-session => memory-session-store}/index.ts (94%) rename examples/nodejs/basic_auth/{app-session => memory-session-store}/store.ts (100%) diff --git a/examples/nodejs/basic_auth/index.ts b/examples/nodejs/basic_auth/index.ts index 906dbfc..baf8d46 100644 --- a/examples/nodejs/basic_auth/index.ts +++ b/examples/nodejs/basic_auth/index.ts @@ -1,5 +1,5 @@ import { Node } from "./node" -import { AppSession } from "./app-session" +import { AppSession } from "./memory-session-store" import { randomBytes } from "tweetnacl"; const session = new AppSession(); diff --git a/examples/nodejs/basic_auth/app-session/index.ts b/examples/nodejs/basic_auth/memory-session-store/index.ts similarity index 94% rename from examples/nodejs/basic_auth/app-session/index.ts rename to examples/nodejs/basic_auth/memory-session-store/index.ts index bac662c..c1d2229 100644 --- a/examples/nodejs/basic_auth/app-session/index.ts +++ b/examples/nodejs/basic_auth/memory-session-store/index.ts @@ -1,7 +1,7 @@ import { Context } from "../context"; import { Store } from "./store"; -export class AppSession { +export class MemorySessionStore { sessionid?: string | null; store?: any; diff --git a/examples/nodejs/basic_auth/app-session/store.ts b/examples/nodejs/basic_auth/memory-session-store/store.ts similarity index 100% rename from examples/nodejs/basic_auth/app-session/store.ts rename to examples/nodejs/basic_auth/memory-session-store/store.ts From 244a495da3713042c2ed23cb087c54f9935e2036 Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Tue, 23 Jun 2020 10:19:16 +0000 Subject: [PATCH 04/10] Fix typos and remove sessionid from MSS constructor. --- examples/nodejs/basic_auth/index.ts | 4 ++-- examples/nodejs/basic_auth/memory-session-store/index.ts | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/nodejs/basic_auth/index.ts b/examples/nodejs/basic_auth/index.ts index baf8d46..3a5b948 100644 --- a/examples/nodejs/basic_auth/index.ts +++ b/examples/nodejs/basic_auth/index.ts @@ -1,8 +1,8 @@ import { Node } from "./node" -import { AppSession } from "./memory-session-store" +import { MemorySessionStore } from "./memory-session-store" import { randomBytes } from "tweetnacl"; -const session = new AppSession(); +const session = new MemorySessionStore(); const users = [ { id: "john", diff --git a/examples/nodejs/basic_auth/memory-session-store/index.ts b/examples/nodejs/basic_auth/memory-session-store/index.ts index c1d2229..6271b54 100644 --- a/examples/nodejs/basic_auth/memory-session-store/index.ts +++ b/examples/nodejs/basic_auth/memory-session-store/index.ts @@ -2,7 +2,6 @@ import { Context } from "../context"; import { Store } from "./store"; export class MemorySessionStore { - sessionid?: string | null; store?: any; constructor() { @@ -10,7 +9,7 @@ export class MemorySessionStore { } public load(sessionid: string): any { - return this.sessionid? Object.assign(this.store.get(sessionid), {id: sessionid}) : null + return sessionid? Object.assign(this.store.get(sessionid), {id: sessionid}) : null } public create(sessionid: string, session: any) { From 82d46e705b37631ef93ce76c08fba0004c8b7225 Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Tue, 23 Jun 2020 10:21:30 +0000 Subject: [PATCH 05/10] Change store type requirement. --- examples/nodejs/basic_auth/memory-session-store/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/nodejs/basic_auth/memory-session-store/index.ts b/examples/nodejs/basic_auth/memory-session-store/index.ts index 6271b54..02f6c33 100644 --- a/examples/nodejs/basic_auth/memory-session-store/index.ts +++ b/examples/nodejs/basic_auth/memory-session-store/index.ts @@ -2,13 +2,13 @@ import { Context } from "../context"; import { Store } from "./store"; export class MemorySessionStore { - store?: any; + store?: Store; constructor() { this.store = new Store(); } - public load(sessionid: string): any { + public load(sessionid: string) { return sessionid? Object.assign(this.store.get(sessionid), {id: sessionid}) : null } From adafc806959f47b75f47a309aef092383e4ce598 Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Tue, 23 Jun 2020 15:08:06 +0000 Subject: [PATCH 06/10] Separate store logic. --- examples/nodejs/.DS_Store | Bin 0 -> 6148 bytes examples/nodejs/basic_auth/index.ts | 5 ++-- .../index.ts | 23 ++++++++++++------ .../store.ts => session-store/memory.ts} | 2 +- nodejs/package.json | 3 ++- 5 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 examples/nodejs/.DS_Store rename examples/nodejs/basic_auth/{memory-session-store => session-store}/index.ts (50%) rename examples/nodejs/basic_auth/{memory-session-store/store.ts => session-store/memory.ts} (98%) diff --git a/examples/nodejs/.DS_Store b/examples/nodejs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..996e79d59b8ead3e1a9b791bee702b3cc820bb11 GIT binary patch literal 6148 zcmeHK%}xR_5S{|+qA_wXkz+63I6y@3VzOEB;LQZ12Q{!OL^i=)!!B+VG5Z?&Mm~YB z<4ju!1U#7-LuQicH=Un0{kmzl03e)Urvgv_01K5clgDO>P@Hr@GR8wF)EIZr0vCo5 zLvJCQ9siL5+Ph8gaMvR6VP^llBzpAvp@;EL@3HSkak=~@GTGeP`i7OyTlsD4w%H4l zX6(kp$Z-ePs^@pQp0O{&us^k3@6zukt-|g}7{sn0bO$r(H&=ep2@@wA2AxQabMD4H ztW^`W3dPZ=TC0>~<>+u+lB0UPT$0s;+IVbPd;68+v-ZRD%jk9d_O2Ng_%SNkF*tz_ zG?p&*sW}MxVQ`P}N$sSDkr`kHn1K~!z#Mhf)(WnTm&6P(1HWT{&IgG~Xd6s5s-puN z`hBE$j*tXxdP@*WgSNp`BSuh!E=AO(!aOmAE=RvKdA7k+qb>)bX2x;M%)-1-gqj`w zQl*2iHFC=gFaz@pWOcVd_y6h7@BjHC?lA+*z)CS7a*bxg!6liybzyOI*GkkjDhcJK m8mA>_sH+%r=_)RwDnY*_1JO2^YD5nT{|G1=xM2qVl!0%U4O7 Date: Tue, 23 Jun 2020 15:35:37 +0000 Subject: [PATCH 07/10] Provide store interface. --- examples/nodejs/basic_auth/index.ts | 7 ++-- .../nodejs/basic_auth/session-store/index.ts | 32 ++++++------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/examples/nodejs/basic_auth/index.ts b/examples/nodejs/basic_auth/index.ts index a3512de..6470fd5 100644 --- a/examples/nodejs/basic_auth/index.ts +++ b/examples/nodejs/basic_auth/index.ts @@ -1,8 +1,9 @@ import { Node } from "./node" import { SessionStore } from "./session-store" +import { Memory } from "./session-store/memory" import { randomBytes } from "tweetnacl"; -const session = new SessionStore("memory"); +const session = new SessionStore(new Memory()); const users = [ { @@ -29,7 +30,7 @@ const main = async () => { if (authenticated) { const sid = Buffer.from(randomBytes(32)).toString('hex'); session.create(sid, authenticated); - ctx.json(session.load(sid)); + ctx.json(session.store.get(sid)); } else { ctx.json({ @@ -53,7 +54,7 @@ const main = async () => { } }, logout: (ctx) => { - const sess = session.load(ctx.headers["params.sid"]) + const sess = session.load(ctx.headers) session.clear(sess.id) } }, diff --git a/examples/nodejs/basic_auth/session-store/index.ts b/examples/nodejs/basic_auth/session-store/index.ts index e328dc8..928bf9a 100644 --- a/examples/nodejs/basic_auth/session-store/index.ts +++ b/examples/nodejs/basic_auth/session-store/index.ts @@ -1,33 +1,19 @@ -import { Context } from "../context"; -import { Memory } from "./memory"; - export class SessionStore { - store: Memory; - mode: string; + store: any; - constructor(mode: string) { - this.mode = mode - switch(mode) { - case "memory": { - this.store = new Memory(); - break; - } - default: { - this.store = new Memory(); - break; - } - } + constructor(store: any) { + this.store = store } - public load(sessionid: string) { - return sessionid? Object.assign(this.store.get(sessionid), {id: sessionid}) : null + public load(headers: { [key:string]:string }) { + return this.store.get(headers.sessionId) } - public create(sessionid: string, session: any) { - this.store.set(sessionid, session) + public create(sessionId: string, session: any) { + this.store.set(sessionId, session) } - public clear(sessionid: string) { - this.store.destroy(sessionid) + public clear(sessionId: string) { + this.store.destroy(sessionId) } } \ No newline at end of file From f3b903ffc2858839e9e22baf906bbaa6911455c4 Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Wed, 24 Jun 2020 04:32:59 +0000 Subject: [PATCH 08/10] Remove yarn dev dependency in nodejs folder. --- nodejs/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nodejs/package.json b/nodejs/package.json index edab06f..fde9f11 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -30,7 +30,6 @@ "mocha": "^8.0.1", "prettier": "^2.0.5", "ts-node": "^8.10.2", - "typescript": "^3.9.5", - "yarn": "^1.22.4" + "typescript": "^3.9.5" } } From 4b5ac673bc4c1eadd035980cc64fa6e47ed0e870 Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Fri, 26 Jun 2020 17:47:36 +0000 Subject: [PATCH 09/10] Added salted hashing passwords. --- examples/nodejs/basic_auth/index.ts | 6 ++++-- .../nodejs/basic_auth/session-store/index.ts | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/examples/nodejs/basic_auth/index.ts b/examples/nodejs/basic_auth/index.ts index 6470fd5..7b824e7 100644 --- a/examples/nodejs/basic_auth/index.ts +++ b/examples/nodejs/basic_auth/index.ts @@ -2,7 +2,9 @@ import { Node } from "./node" import { SessionStore } from "./session-store" import { Memory } from "./session-store/memory" import { randomBytes } from "tweetnacl"; +import bcrypt from "bcryptjs"; +const salt = bcrypt.genSaltSync(10); const session = new SessionStore(new Memory()); const users = [ @@ -27,7 +29,7 @@ const main = async () => { login: (ctx) => { if (ctx.headers["params.id"] && ctx.headers["params.password"]) { const authenticated = authenticate(ctx.headers["params.id"], ctx.headers["params.password"]); - if (authenticated) { + if (authenticated && bcrypt.compareSync(ctx.headers["params.password"], authenticated.password)) { const sid = Buffer.from(randomBytes(32)).toString('hex'); session.create(sid, authenticated); ctx.json(session.store.get(sid)); @@ -48,7 +50,7 @@ const main = async () => { if (ctx.headers["params.id"] && ctx.headers["params.password"]) { users.push({ id: ctx.headers["params.id"], - password: ctx.headers["params.password"] + password: bcrypt.hashSync(ctx.headers["params.password"], salt) }) ctx.send('done'); } diff --git a/examples/nodejs/basic_auth/session-store/index.ts b/examples/nodejs/basic_auth/session-store/index.ts index 928bf9a..f772c8e 100644 --- a/examples/nodejs/basic_auth/session-store/index.ts +++ b/examples/nodejs/basic_auth/session-store/index.ts @@ -6,11 +6,22 @@ export class SessionStore { } public load(headers: { [key:string]:string }) { - return this.store.get(headers.sessionId) + if(!headers.sessionId) { + return null + } else { + return this.store.get(headers.sessionId) + } } - public create(sessionId: string, session: any) { - this.store.set(sessionId, session) + public create(sessionId: string, payload: any) { + var maxAge = 86400; + var oneDay = 86400; + var now = new Date().getTime(); + var expiry = maxAge ? now + maxAge : now + oneDay; + this.store.set(sessionId, Object.assign({ + sid: sessionId, + expiry: expiry + }, payload)) } public clear(sessionId: string) { From ce19c251e83d6b66565ac158b9132f91f857dd82 Mon Sep 17 00:00:00 2001 From: johnhorsema Date: Fri, 26 Jun 2020 17:50:20 +0000 Subject: [PATCH 10/10] Removed default users. --- examples/nodejs/basic_auth/index.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/examples/nodejs/basic_auth/index.ts b/examples/nodejs/basic_auth/index.ts index 7b824e7..fc4afcc 100644 --- a/examples/nodejs/basic_auth/index.ts +++ b/examples/nodejs/basic_auth/index.ts @@ -7,16 +7,7 @@ import bcrypt from "bcryptjs"; const salt = bcrypt.genSaltSync(10); const session = new SessionStore(new Memory()); -const users = [ - { - id: "john", - password: "123" - }, - { - id: "mary", - password: "456" - } -] +const users = [] const authenticate = (id: string, password: string) => { return users.find(u => u.id === id)