Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@turbasen/auth

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@turbasen/auth - npm Package Compare versions

Comparing version 2.1.0 to 3.0.0

lib/AbstractUser.js

132

index.js
'use strict';
const HttpError = require('@starefossen/http-error');
const redis = require('@turbasen/db-redis');
const mongo = require('@turbasen/db-mongo');
const UnauthUser = require('./lib/User').UnauthUser;
const AuthUser = require('./lib/User').AuthUser;
const AbstractUser = require('./lib/AbstractUser');
const UnauthUser = require('./lib/UnauthUser');
const AuthUser = require('./lib/AuthUser');
const CACHE_VALID = process.env.NTB_CACHE_VALID || 60 * 60 * 1000;
const CACHE_INVALID = process.env.NTB_CACHE_INVALID || 24 * 60 * 60 * 1000;
const API_ENV = process.env.NTB_API_ENV || 'dev';
const RATELIMIT_UNAUTH = process.env.NTB_RATELIMIT_UNAUTH || 100;
module.exports = () => (req, res, next) => {

@@ -21,11 +15,11 @@ let promise;

const token = req.headers.authorization.split(' ');
promise = module.exports.getUserByToken(token[1]);
promise = AuthUser.getByKey(token[1]);
// API key through URL query parameter
} else if (req.query && req.query.api_key) {
promise = module.exports.getUserByToken(req.query.api_key);
promise = AuthUser.getByKey(req.query.api_key);
// No API key
} else {
promise = module.exports.getUserByIp(
promise = UnauthUser.getByKey(
req.headers['x-forwarded-for'] || req.connection.remoteAddres

@@ -38,2 +32,3 @@ );

// X-User headers
res.set('X-User-Auth', user.auth);

@@ -44,5 +39,7 @@ if (user.auth) {

// X-Rate-Limit headers
res.set('X-RateLimit-Limit', user.limit);
res.set('X-RateLimit-Reset', user.reset);
// Check if user has remaining rate limit quota
if (!user.hasRemainingQuota()) {

@@ -56,4 +53,7 @@ res.set('X-RateLimit-Remaining', 0);

// Charge user for this request
res.set('X-RateLimit-Remaining', user.charge());
// Check if user can execute the HTTP method. Only authenticated users are
// allowed to execute POST, PUT, and DELETE requests.
if (!user.can(req.method)) {

@@ -65,14 +65,5 @@ return next(new HttpError(

res.on('finish', function resOnFinishCb() {
// Uncharge user when certain cache features are used.
// 304 Not Modified, and 412 Precondition Failed
if (this.statusCode === 304 || this.statusCode === 412) {
this.req.user.uncharge();
}
// Attach the on finish callback which updates the user rate limit in cache.
res.on('finish', module.exports.onFinish);
if (this.req.user.getCharge() > 0) {
redis.hincrby(this.req.user.cacheKey, 'remaining', -1);
}
});
return next();

@@ -82,89 +73,16 @@ }).catch(next);

module.exports.getUserByIp = function getUserByIp(key) {
return new Promise((resolve, reject) => {
redis.hgetall(AuthUser.getCacheKey(key), (redisErr, data) => {
if (redisErr) { return reject(redisErr); }
module.exports.onFinish = function onFinish() {
// Uncharge user when certain cache features are used.
// 304 Not Modified, and 412 Precondition Failed
if (this.statusCode === 304 || this.statusCode === 412) {
this.req.user.uncharge();
}
if (data && data.limit) {
return resolve(new UnauthUser(key, data));
} else {
const expireat = module.exports.expireat(CACHE_VALID);
const user = new UnauthUser(key, {
limit: RATELIMIT_UNAUTH,
remaining: RATELIMIT_UNAUTH,
reset: expireat,
});
redis.hmset(AuthUser.getCacheKey(key), user.toObject());
redis.expireat(AuthUser.getCacheKey(key), expireat);
return resolve(user);
}
});
});
// Update user rate-limit in cache if it has changed.
this.req.user.update();
};
module.exports.getUserByToken = function getUserByToken(key) {
return new Promise((resolve, reject) => {
redis.hgetall(UnauthUser.getCacheKey(key), (redisErr, data) => {
if (redisErr) { return reject(redisErr); }
if (data && data.access) {
if (data.access === 'true') {
return resolve(new AuthUser(key, data));
} else {
return reject(new HttpError(`Bad credentials for user "${key}"`, 401));
}
}
const query = {
[`apps.key.${API_ENV}`]: key,
'apps.active': true,
};
const opts = {
fields: {
provider: true,
apps: true,
},
};
return mongo.api.users.findOne(query, opts, (mongoErr, doc) => {
if (mongoErr) { return reject(mongoErr); }
if (!doc) {
const expireat = module.exports.expireat(CACHE_INVALID);
redis.hset(AuthUser.getCacheKey(key), 'access', 'false');
redis.expireat(AuthUser.getCacheKey(key), expireat);
return reject(new HttpError(`Bad credentials for user "${key}"`, 401));
}
const app = doc.apps.find(item => item.key[API_ENV] === key);
const expireat = module.exports.expireat(CACHE_VALID);
const user = new AuthUser(key, {
provider: doc.provider,
app: app.name,
limit: app.limit[API_ENV],
remaining: app.limit[API_ENV],
reset: expireat,
});
redis.hmset(AuthUser.getCacheKey(key), user.toObject());
redis.expireat(AuthUser.getCacheKey(key), expireat);
return resolve(user);
});
});
});
};
module.exports.expireat = function expireat(seconds) {
return Math.floor((new Date().getTime() + seconds) / 1000);
};
module.exports.middleware = module.exports();
module.exports.AbstractUser = AbstractUser;
module.exports.AuthUser = AuthUser;
module.exports.UnauthUser = UnauthUser;
{
"name": "@turbasen/auth",
"version": "2.1.0",
"version": "3.0.0",
"description": "Authentication middleware used internally at Nasjonal Turbase API",

@@ -5,0 +5,0 @@ "main": "index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc