Skip to content

Commit 833ea4a

Browse files
n3rdc4ptnandreaskienleCopilot
authored
style: Update code formatting for consistency and readability & fixed… (#173)
Co-authored-by: Andreas Kienle <andreas.kienle@sap.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent dcc71e3 commit 833ea4a

File tree

10 files changed

+251
-231
lines changed

10 files changed

+251
-231
lines changed

.prettierrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
"semi": true,
33
"tabWidth": 2,
44
"trailingComma": "all",
5-
"printWidth": 80,
5+
"printWidth": 120,
66
"singleQuote": true
77
}

server/app.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import path, { join, dirname } from "node:path";
2-
import { fileURLToPath } from "node:url";
3-
import AutoLoad from "@fastify/autoload";
4-
import envPlugin from "./config/env.js";
5-
import encryptedSession from "./encrypted-session.js";
1+
import path, { join, dirname } from 'node:path';
2+
import { fileURLToPath } from 'node:url';
3+
import AutoLoad from '@fastify/autoload';
4+
import envPlugin from './config/env.js';
5+
import encryptedSession from './encrypted-session.js';
66

77
export const options = {};
88

@@ -16,14 +16,12 @@ export default async function (fastify, opts) {
1616
});
1717

1818
await fastify.register(AutoLoad, {
19-
dir: join(__dirname, "plugins"),
19+
dir: join(__dirname, 'plugins'),
2020
options: { ...opts },
2121
});
2222

2323
await fastify.register(AutoLoad, {
24-
dir: join(__dirname, "routes"),
24+
dir: join(__dirname, 'routes'),
2525
options: { ...opts },
2626
});
27-
28-
29-
}
27+
}

server/encrypted-session.js

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,38 @@
1-
import secureSession from "@fastify/secure-session";
2-
import fp from "fastify-plugin";
3-
import fastifyCookie from "@fastify/cookie";
1+
import secureSession from '@fastify/secure-session';
2+
import fp from 'fastify-plugin';
3+
import fastifyCookie from '@fastify/cookie';
44
import fastifySession from '@fastify/session';
5-
import crypto from "node:crypto"
5+
import crypto from 'node:crypto';
66

7-
8-
// name of the request decorator this plugin exposes. Using request.encryptedSession can be used with set, get, clear delete
7+
// name of the request decorator this plugin exposes. Using request.encryptedSession can be used with set, get, clear delete
98
// functions and the encryption will then be handled in this plugin.
10-
export const REQUEST_DECORATOR = "encryptedSession";
9+
export const REQUEST_DECORATOR = 'encryptedSession';
1110
// name of the request decorator of the secure-session library that stores its session data in an encrypted cookie on user side.
12-
export const ENCRYPTED_COOKIE_REQUEST_DECORATOR = "encryptedSessionInternal";
11+
export const ENCRYPTED_COOKIE_REQUEST_DECORATOR = 'encryptedSessionInternal';
1312
// name of the request decorator of the session library that is used as underlying store for this library.
14-
export const UNDERLYING_SESSION_NAME_REQUEST_DECORATOR = "underlyingSessionNotPerUserEncrypted";
13+
export const UNDERLYING_SESSION_NAME_REQUEST_DECORATOR = 'underlyingSessionNotPerUserEncrypted';
1514

1615
// name of the secure-session cookie that stores the encryption key on user side.
17-
export const ENCRYPTION_KEY_COOKIE_NAME = "session_encryption_key";
16+
export const ENCRYPTION_KEY_COOKIE_NAME = 'session_encryption_key';
1817
// the key used to store the encryption key in the secure-session cookie on user side.
19-
export const ENCRYPTED_COOKIE_KEY_ENCRYPTION_KEY = "encryptionKey";
18+
export const ENCRYPTED_COOKIE_KEY_ENCRYPTION_KEY = 'encryptionKey';
2019
// name of the cookie that stores the session identifier on user side.
21-
export const SESSION_COOKIE_NAME = "session-cookie";
20+
export const SESSION_COOKIE_NAME = 'session-cookie';
2221

2322
async function encryptedSession(fastify) {
2423
const { COOKIE_SECRET, SESSION_SECRET, NODE_ENV } = fastify.config;
2524

2625
await fastify.register(fastifyCookie);
2726

2827
fastify.register(secureSession, {
29-
secret: Buffer.from(COOKIE_SECRET, "hex"),
28+
secret: Buffer.from(COOKIE_SECRET, 'hex'),
3029
cookieName: ENCRYPTION_KEY_COOKIE_NAME,
3130
sessionName: ENCRYPTED_COOKIE_REQUEST_DECORATOR,
3231
cookie: {
33-
path: "/",
32+
path: '/',
3433
httpOnly: true,
35-
sameSite: "lax",
36-
secure: NODE_ENV === "production",
34+
sameSite: 'lax',
35+
secure: NODE_ENV === 'production',
3736
maxAge: 60 * 60 * 24 * 7, // 7 days
3837
},
3938
});
@@ -42,29 +41,29 @@ async function encryptedSession(fastify) {
4241
cookieName: SESSION_COOKIE_NAME,
4342
// sessionName: UNDERLYING_SESSION_NAME, //NOT POSSIBLE to change the name it is decorated on the request object
4443
cookie: {
45-
path: "/",
44+
path: '/',
4645
httpOnly: true,
47-
sameSite: "lax",
48-
secure: NODE_ENV === "production",
46+
sameSite: 'lax',
47+
secure: NODE_ENV === 'production',
4948
maxAge: 60 * 60 * 24 * 7, // 7 days
5049
},
5150
});
5251

5352
fastify.addHook('onRequest', (request, _reply, next) => {
5453
const userEncryptionKey = getUserEncryptionKeyFromUserCookie(request);
5554
if (!userEncryptionKey) {
56-
request.log.info({ "plugin": "encrypted-session" }, "user-side encryption key not found, creating new one");
55+
request.log.info({ plugin: 'encrypted-session' }, 'user-side encryption key not found, creating new one');
5756

5857
let newEncryptionKey = generateSecureEncryptionKey();
5958
setUserEncryptionKeyIntoUserCookie(request, newEncryptionKey);
60-
request[REQUEST_DECORATOR] = createStore()
61-
newEncryptionKey = undefined
59+
request[REQUEST_DECORATOR] = createStore();
60+
newEncryptionKey = undefined;
6261
} else {
63-
request.log.info({ "plugin": "encrypted-session" }, "user-side encryption key found, using existing one");
62+
request.log.info({ plugin: 'encrypted-session' }, 'user-side encryption key found, using existing one');
6463

65-
const loadedEncryptionKey = Buffer.from(userEncryptionKey, "base64");
64+
const loadedEncryptionKey = Buffer.from(userEncryptionKey, 'base64');
6665

67-
const encryptedStore = request.session.get("encryptedStore");
66+
const encryptedStore = request.session.get('encryptedStore');
6867
if (encryptedStore) {
6968
try {
7069
const { cipherText, iv, tag } = encryptedStore;
@@ -73,28 +72,31 @@ async function encryptedSession(fastify) {
7372
const decryptedStore = JSON.parse(decryptedCypherText);
7473
request[REQUEST_DECORATOR] = createStore(decryptedStore);
7574
} catch (error) {
76-
request.log.error({ "plugin": "encrypted-session" }, "Failed to parse encrypted session store", error);
75+
request.log.error({ plugin: 'encrypted-session' }, 'Failed to parse encrypted session store', error);
7776
request[REQUEST_DECORATOR] = createStore();
7877
}
7978
} else {
8079
// we could not parse the encrypted store, so we create a new one and it would overwrite the previously stored store.
81-
request.log.info({ "plugin": "encrypted-session" }, "No encrypted store found, creating new empty store");
80+
request.log.info({ plugin: 'encrypted-session' }, 'No encrypted store found, creating new empty store');
8281
request[REQUEST_DECORATOR] = createStore();
8382
}
8483
}
8584

86-
next()
87-
})
85+
next();
86+
});
8887

8988
//TODO maybe move to onResponse after res is send. Lifecycle Doc https://fastify.dev/docs/latest/Reference/Lifecycle/
9089
// onSend is called before the response is send. Here we take encrypt the Session object and store it in the fastify-session.
9190
// Then we also want to make sure the unencrypted object is removed from memory
92-
fastify.addHook('onSend', async (request, reply, _payload) => {
93-
const encryptionKey = Buffer.from(getUserEncryptionKeyFromUserCookie(request), "base64");
91+
fastify.addHook('onSend', async (request, _reply, payload) => {
92+
const encryptionKey = Buffer.from(getUserEncryptionKeyFromUserCookie(request), 'base64');
9493
if (!encryptionKey) {
9594
// if no encryption key is found in the secure session, we cannot encrypt the store. This should not happen since an encrption key is generated when the request arrived
96-
request.log.error({ "plugin": "encrypted-session" }, "No encryption key found in secure session, cannot encrypt store");
97-
throw new Error("No encryption key found in secure session, cannot encrypt store");
95+
request.log.error(
96+
{ plugin: 'encrypted-session' },
97+
'No encryption key found in secure session, cannot encrypt store',
98+
);
99+
throw new Error('No encryption key found in secure session, cannot encrypt store');
98100
}
99101

100102
//we store everything in one value in the session, that might be problematic for future redis with expiration times per key. we might want to split this
@@ -105,17 +107,19 @@ async function encryptedSession(fastify) {
105107
delete request[REQUEST_DECORATOR];
106108
request[REQUEST_DECORATOR] = null;
107109

108-
request.session.set("encryptedStore", {
110+
request.session.set('encryptedStore', {
109111
cipherText,
110112
iv,
111113
tag,
112114
});
113-
await request.session.save()
114-
request.log.info("store encrypted and set into request.session.encryptedStore");
115-
})
115+
await request.session.save();
116+
request.log.info('store encrypted and set into request.session.encryptedStore');
117+
118+
return payload;
119+
});
116120

117121
function getUserEncryptionKeyFromUserCookie(request) {
118-
return request[ENCRYPTED_COOKIE_REQUEST_DECORATOR].get(ENCRYPTED_COOKIE_KEY_ENCRYPTION_KEY)
122+
return request[ENCRYPTED_COOKIE_REQUEST_DECORATOR].get(ENCRYPTED_COOKIE_KEY_ENCRYPTION_KEY);
119123
}
120124

121125
function setUserEncryptionKeyIntoUserCookie(request, key) {
@@ -163,33 +167,33 @@ function generateSecureEncryptionKey() {
163167
// it outputs cipherText (bas64 encoded string), the initialisation vector (iv) (hex string) and the authentication tag (hex string).
164168
function encryptSymetric(plaintext, key) {
165169
if (key == undefined) {
166-
throw new Error("Key must be provided");
170+
throw new Error('Key must be provided');
167171
}
168172
if (key.length < 32) {
169-
throw new Error("Key must be at least 32 byte = 256 bits long");
173+
throw new Error('Key must be at least 32 byte = 256 bits long');
170174
}
171175

172176
if (!(key instanceof Buffer)) {
173-
throw new Error("Key must be a Buffer");
177+
throw new Error('Key must be a Buffer');
174178
}
175179

176180
if (plaintext == undefined) {
177-
throw new Error("Plaintext must be provided");
181+
throw new Error('Plaintext must be provided');
178182
}
179183

180-
if (typeof plaintext !== "string") {
181-
throw new Error("Plaintext must be a string utf8 encoded");
184+
if (typeof plaintext !== 'string') {
185+
throw new Error('Plaintext must be a string utf8 encoded');
182186
}
183187

184-
if (!crypto.getCiphers().includes("aes-256-gcm")) {
185-
throw new Error("Cipher suite aes-256-gcm is not available");
188+
if (!crypto.getCiphers().includes('aes-256-gcm')) {
189+
throw new Error('Cipher suite aes-256-gcm is not available');
186190
}
187191

188192
// initialisation vector. Needs to be stored along the cipherText.
189193
// MUST NOT be reused and MUST be randomly generated for EVERY encryption operation. Otherwise using the same key would be insecure.
190194
const iv = crypto.randomBytes(12);
191195

192-
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
196+
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
193197
let cipherText = cipher.update(plaintext, 'utf8', 'base64');
194198
cipherText += cipher.final('base64');
195199

@@ -201,41 +205,41 @@ function encryptSymetric(plaintext, key) {
201205
cipherText,
202206
iv: iv.toString('base64'),
203207
tag: tag.toString('base64'),
204-
}
208+
};
205209
}
206210

207211
// uses authenticated symetric encryption (aes-256-gcm) to decrypt the ciphertext with the key.
208212
// requires the ciphertext, the initialisation vector (iv)(hex string), the authentication tag (tag) (hex string) and the key (buffer) to be provided.
209213
//it thows an error if the decryption or tag verification fails
210214
function decryptSymetric(cipherText, iv, tag, key) {
211215
if (key == undefined) {
212-
throw new Error("Key must be provided");
216+
throw new Error('Key must be provided');
213217
}
214218
if (key.length < 32) {
215-
throw new Error("Key must be at least 32 byte = 256 bits long");
219+
throw new Error('Key must be at least 32 byte = 256 bits long');
216220
}
217221

218222
if (!(key instanceof Buffer)) {
219-
throw new Error("Key must be a Buffer");
223+
throw new Error('Key must be a Buffer');
220224
}
221225

222226
if (cipherText == undefined) {
223-
throw new Error("Ciphertext must be provided");
227+
throw new Error('Ciphertext must be provided');
224228
}
225229

226-
if (typeof cipherText !== "string") {
227-
throw new Error("Ciphertext must be a string utf8 encoded");
230+
if (typeof cipherText !== 'string') {
231+
throw new Error('Ciphertext must be a string utf8 encoded');
228232
}
229233

230-
if (!crypto.getCiphers().includes("aes-256-gcm")) {
231-
throw new Error("Cipher suite aes-256-gcm is not available");
234+
if (!crypto.getCiphers().includes('aes-256-gcm')) {
235+
throw new Error('Cipher suite aes-256-gcm is not available');
232236
}
233237

234-
const decipher = crypto.createDecipheriv("aes-256-gcm", key, Buffer.from(iv, 'base64'));
238+
const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(iv, 'base64'));
235239
decipher.setAuthTag(Buffer.from(tag, 'base64'));
236240

237241
let decrypted = decipher.update(cipherText, 'base64', 'utf8');
238242
decrypted += decipher.final('utf8');
239243

240244
return decrypted;
241-
}
245+
}

0 commit comments

Comments
 (0)