chore: Unify term types

This commit is contained in:
Maksim Eltyshev
2026-02-10 21:14:56 +01:00
parent e7326303cd
commit a82ae49fe4
14 changed files with 31 additions and 176 deletions
@@ -31,7 +31,7 @@
* type: string
* minLength: 64
* maxLength: 64
* description: Terms signature hash based on user role
* description: Terms signature hash
* example: 940226c4c41f51afe3980ceb63704e752636526f4c52a4ea579e85b247493d94
* initialLanguage:
* type: string
@@ -184,14 +184,12 @@ module.exports = {
}
if (!user.termsSignature) {
const termsSignature = sails.hooks.terms.getSignatureByUserRole(user.role);
if (inputs.signature !== termsSignature) {
if (!sails.hooks.terms.isSignatureValid(inputs.signature)) {
throw Errors.INVALID_SIGNATURE;
}
const values = {
termsSignature,
termsSignature: inputs.signature,
termsAcceptedAt: new Date().toISOString(),
};
+2 -20
View File
@@ -5,7 +5,7 @@
/**
* @swagger
* /terms/{type}:
* /terms:
* get:
* summary: Get terms and conditions
* description: Retrieves terms and conditions in the specified language.
@@ -13,14 +13,6 @@
* - Terms
* operationId: getTerms
* parameters:
* - name: type
* in: path
* required: true
* description: Type of terms to retrieve
* schema:
* type: string
* enum: [general, extended]
* example: general
* - name: language
* in: query
* required: false
@@ -47,11 +39,6 @@
* - content
* - signature
* properties:
* type:
* type: string
* enum: [general, extended]
* description: Type of terms
* example: general
* language:
* type: string
* enum: [de-DE, en-US]
@@ -76,11 +63,6 @@
module.exports = {
inputs: {
type: {
type: 'string',
isIn: Object.values(sails.hooks.terms.Types),
required: true,
},
language: {
type: 'string',
isIn: User.LANGUAGES,
@@ -88,7 +70,7 @@ module.exports = {
},
async fn(inputs) {
const terms = await sails.hooks.terms.getPayload(inputs.type, inputs.language);
const terms = await sails.hooks.terms.getPayload(inputs.language);
return {
item: terms,
@@ -56,7 +56,7 @@ module.exports = {
}
}
if (!sails.hooks.terms.hasSignature(inputs.user.termsSignature)) {
if (!sails.hooks.terms.isSignatureValid(inputs.user.termsSignature)) {
const { token: pendingToken, payload: pendingTokenPayload } =
sails.helpers.utils.createJwtToken(
AccessTokenSteps.ACCEPT_TERMS,
@@ -82,12 +82,9 @@ module.exports = {
);
}
const termsType = sails.hooks.terms.getTypeByUserRole(inputs.user.role);
throw {
termsAcceptanceRequired: {
pendingToken,
termsType,
message: 'Terms acceptance required',
step: AccessTokenSteps.ACCEPT_TERMS,
},
-1
View File
@@ -34,7 +34,6 @@ module.exports = {
},
},
language: inputs.record.language || sails.config.i18n.defaultLocale,
termsType: sails.hooks.terms.getTypeByUserRole(inputs.record.role),
};
const gravatarUrl = sails.helpers.users.buildGravatarUrl(inputs.record);
+13 -40
View File
@@ -14,22 +14,18 @@
const fsPromises = require('fs').promises;
const crypto = require('crypto');
const Types = {
GENERAL: 'general',
EXTENDED: 'extended',
};
const LANGUAGES = ['de-DE', 'en-US'];
const DEFAULT_LANGUAGE = 'en-US';
const getContent = (language = DEFAULT_LANGUAGE) =>
fsPromises.readFile(`${sails.config.appPath}/terms/${language}.md`, 'utf8');
const hashContent = (content) => crypto.createHash('sha256').update(content).digest('hex');
module.exports = function defineTermsHook(sails) {
let signatureByType;
let signaturesSet;
let signature;
return {
Types,
LANGUAGES,
/**
@@ -39,49 +35,26 @@ module.exports = function defineTermsHook(sails) {
async initialize() {
sails.log.info('Initializing custom hook (`terms`)');
signatureByType = {
[Types.GENERAL]: hashContent(await this.getContent(Types.GENERAL)),
[Types.EXTENDED]: hashContent(await this.getContent(Types.EXTENDED)),
};
signaturesSet = new Set(Object.values(signatureByType));
const content = await getContent();
signature = hashContent(content);
},
async getPayload(type, language = DEFAULT_LANGUAGE) {
if (!Object.values(Types).includes(type)) {
throw new Error(`Unknown type: ${type}`);
}
async getPayload(language = DEFAULT_LANGUAGE) {
if (!LANGUAGES.includes(language)) {
language = DEFAULT_LANGUAGE; // eslint-disable-line no-param-reassign
}
const content = await getContent(language);
return {
type,
language,
content: await this.getContent(type, language),
signature: this.getSignatureByType(type),
content,
signature,
};
},
getTypeByUserRole(userRole) {
return userRole === User.Roles.ADMIN ? Types.EXTENDED : Types.GENERAL;
},
getContent(type, language = DEFAULT_LANGUAGE) {
return fsPromises.readFile(`${sails.config.appPath}/terms/${language}/${type}.md`, 'utf8');
},
getSignatureByType(type) {
return signatureByType[type];
},
getSignatureByUserRole(userRole) {
return signatureByType[this.getTypeByUserRole(userRole)];
},
hasSignature(signature) {
return signaturesSet.has(signature);
isSignatureValid(value) {
return value === signature;
},
};
};
-6
View File
@@ -24,7 +24,6 @@
* - avatar
* - phone
* - organization
* - termsType
* - isDeactivated
* - createdAt
* - updatedAt
@@ -143,11 +142,6 @@
* default: byDefault
* description: Default sort order for projects display (personal field)
* example: byDefault
* termsType:
* type: string
* enum: [general, extended]
* description: Type of terms applicable to the user based on role
* example: general
* isSsoUser:
* type: boolean
* default: false