Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions JavaScript/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,17 @@ class Session extends Map {
return session;
}

static restore(client) {
static async restore(client) {
const { cookie } = client;
if (!cookie) return;
const sessionToken = cookie.token;
if (sessionToken) {
return new Promise((resolve, reject) => {
storage.get(sessionToken, (err, session) => {
if (err) reject(new Error('No session'));
Object.setPrototypeOf(session, Session.prototype);
client.token = sessionToken;
client.session = session;
resolve(session);
});
});
const session = await storage.get(sessionToken);
if (!session) return;
Object.setPrototypeOf(session, Session.prototype);
client.token = sessionToken;
client.session = session;
return session;
}
}

Expand Down
56 changes: 22 additions & 34 deletions JavaScript/storage.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,51 @@
'use strict';

const fs = require('node:fs');
const fs = require('node:fs').promises;
const path = require('node:path');
const v8 = require('node:v8');

const PATH = `${__dirname}/sessions`;

const safePath = (fn) => (token, ...args) => {
const callback = args[args.length - 1];
if (typeof token !== 'string') {
callback(new Error('Invalid session token'));
return;
}
const safePath = (promise) => (token, ...args) => {
if (typeof token !== 'string') throw new Error('Invalid session token');
const fileName = path.join(PATH, token);
if (!fileName.startsWith(PATH)) {
callback(new Error('Invalid session token'));
return;
}
fn(fileName, ...args);
if (!fileName.startsWith(PATH)) throw new Error('Invalid session token');
return promise(fileName, ...args)
};

const readSession = safePath(fs.readFile);
const writeSession = safePath(fs.writeFile);
const deleteSession = safePath(fs.unlink);

class Storage extends Map {
get(key, callback) {
async get(key) {
const value = super.get(key);
if (value) {
callback(null, value);
return;
if (value) return value;
let data;
try {
data = await readSession(key);
} catch (err) {
return undefined;
}
readSession(key, (err, data) => {
if (err) {
callback(err);
return;
}
console.log(`Session loaded: ${key}`);
const session = v8.deserialize(data);
super.set(key, session);
callback(null, session);
});
console.log('Session loaded: ${key}');
const session = v8.deserialize(data);
super.set(key, session);
return session;
}

save(key) {
async save(key) {
const value = super.get(key);
if (value) {
const data = v8.serialize(value);
writeSession(key, data, () => {
console.log(`Session saved: ${key}`);
});
await writeSession(key, data);
console.log(`Session saved: ${key}`);
}
}

delete(key) {
async delete(key) {
console.log('Delete: ', key);
deleteSession(key, () => {
console.log(`Session deleted: ${key}`);
});
await deleteSession(key);
console.log(`Session deleted: ${key}`);
}
}

Expand Down