Oidc node mongodb adapter in normal functions

vimal_adithan

Vimal

Posted on March 1, 2024

Oidc node mongodb adapter in normal functions

const { MongoClient } = require('mongodb');
const snakeCase = require('lodash/snakeCase');

let DB;

const grantable = new Set([
'access_token',
'authorization_code',
'refresh_token',
'device_code',
'backchannel_authentication_request',
]);

const collections = new Set();

function addCollection(name) {
const nu = collections.has(name);
collections.add(name);
if (!nu) {
createIndexes(name);
}
}

function createIndexes(name) {
DB.collection(name).createIndexes([
...(grantable.has(name)
? [{
key: { 'payload.grantId': 1 },
}] : []),
...(name === 'device_code'
? [{
key: { 'payload.userCode': 1 },
unique: true,
}] : []),
...(name === 'session'
? [{
key: { 'payload.uid': 1 },
unique: true,
}] : []),
{
key: { expiresAt: 1 },
expireAfterSeconds: 0,
},
]).catch(console.error);
}

async function upsert(name, _id, payload, expiresIn) {
let expiresAt;

if (expiresIn) {
expiresAt = new Date(Date.now() + (expiresIn * 1000));
}

await updateOne(name, { _id }, { $set: { payload, ...(expiresAt ? { expiresAt } : undefined) } }, { upsert: true });
}

async function find(name, _id) {
const result = await findOne(name, { _id }, { payload: 1 });

if (!result) return undefined;
return result.payload;
}

async function findByUserCode(name, userCode) {
const result = await findOne(name, { 'payload.userCode': userCode }, { payload: 1 });

if (!result) return undefined;
return result.payload;
}

async function findByUid(name, uid) {
const result = await findOne(name, { 'payload.uid': uid }, { payload: 1 });

if (!result) return undefined;
return result.payload;
}

async function destroy(name, _id) {
await deleteOne(name, { _id });
}

async function revokeByGrantId(name, grantId) {
await deleteMany(name, { 'payload.grantId': grantId });
}

async function consume(name, _id) {
await findOneAndUpdate(name, { _id }, { $set: { 'payload.consumed': Math.floor(Date.now() / 1000) } });
}

function findOneAndUpdate(name, filter, update) {
return DB.collection(name).findOneAndUpdate(filter, update);
}

function findOne(name, filter, projection) {
return DB.collection(name).findOne(filter, projection);
}

function updateOne(name, filter, update, options) {
return DB.collection(name).updateOne(filter, update, options);
}

function deleteOne(name, filter) {
return DB.collection(name).deleteOne(filter);
}

function deleteMany(name, filter) {
return DB.collection(name).deleteMany(filter);
}

function connect() {
return MongoClient.connect(process.env.MONGODB_URI)
.then(connection => {
DB = connection.db(connection.s.options.dbName);
});
}

module.exports = {
addCollection,
upsert,
find,
findByUserCode,
findByUid,
destroy,
revokeByGrantId,
consume,
connect
};

💖 💪 🙅 🚩
vimal_adithan
Vimal

Posted on March 1, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related