feat: Add API key authentication (#1254)

Closes #945
This commit is contained in:
Samuel
2025-11-06 20:56:48 +01:00
committed by GitHub
parent 5a2564f575
commit b4cbd32bf2
75 changed files with 1501 additions and 94 deletions

View File

@@ -13,8 +13,9 @@
module.exports = function defineCurrentUserHook(sails) {
const TOKEN_PATTERN = /^Bearer /;
const API_KEY_HEADER_NAME = 'x-api-key';
const getSessionAndUser = async (accessToken, httpOnlyToken) => {
const getSessionAndUserByAccessToken = async (accessToken, httpOnlyToken) => {
let payload;
try {
payload = sails.helpers.utils.verifyJwtToken(accessToken);
@@ -50,6 +51,12 @@ module.exports = function defineCurrentUserHook(sails) {
};
};
const getUserByApiKey = (apiKey) => {
const apiKeyHash = sails.helpers.utils.hash(apiKey);
return User.qm.getOneActiveByApiKeyHash(apiKeyHash);
};
return {
/**
* Runs when this Sails app loads/lifts.
@@ -63,7 +70,8 @@ module.exports = function defineCurrentUserHook(sails) {
before: {
'/api/*': {
async fn(req, res, next) {
const { authorization: authorizationHeader } = req.headers;
const { authorization: authorizationHeader, [API_KEY_HEADER_NAME]: apiKey } =
req.headers;
if (authorizationHeader && TOKEN_PATTERN.test(authorizationHeader)) {
const accessToken = authorizationHeader.replace(TOKEN_PATTERN, '');
@@ -73,7 +81,11 @@ module.exports = function defineCurrentUserHook(sails) {
req.currentUser = User.INTERNAL;
} else {
const { httpOnlyToken } = req.cookies;
const sessionAndUser = await getSessionAndUser(accessToken, httpOnlyToken);
const sessionAndUser = await getSessionAndUserByAccessToken(
accessToken,
httpOnlyToken,
);
if (sessionAndUser) {
const { session, user } = sessionAndUser;
@@ -93,6 +105,20 @@ module.exports = function defineCurrentUserHook(sails) {
}
}
}
} else if (apiKey) {
const user = await getUserByApiKey(apiKey);
if (user) {
if (user.language) {
req.setLocale(user.language);
}
req.currentUser = user;
if (req.isSocket) {
sails.sockets.join(req, `@user:${user.id}`);
}
}
}
return next();
@@ -103,7 +129,10 @@ module.exports = function defineCurrentUserHook(sails) {
const { accessToken, httpOnlyToken } = req.cookies;
if (accessToken) {
const sessionAndUser = await getSessionAndUser(accessToken, httpOnlyToken);
const sessionAndUser = await getSessionAndUserByAccessToken(
accessToken,
httpOnlyToken,
);
if (sessionAndUser) {
const { session, user } = sessionAndUser;
@@ -113,6 +142,16 @@ module.exports = function defineCurrentUserHook(sails) {
currentUser: user,
});
}
} else {
const { [API_KEY_HEADER_NAME]: apiKey } = req.headers;
if (apiKey) {
const user = await getUserByApiKey(apiKey);
if (user) {
req.currentUser = user;
}
}
}
return next();