mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
feat: replace gravatar-url with inline function (#5128)
As #4475 says, MD5 is not available in secure places anymore. This PR swaps out gravatar-url with an inline function using crypto:sha256 which is FIPS-140-2 compliant. Since we only used this method for generating avatar URLs the extra customization wasn't needed and we could hard code the URL parameters. fixes: Linear https://linear.app/unleash/issue/SR-112/gh-support-swap-out-gravatar-url-lib closes: #4475
This commit is contained in:
parent
ab390dbaab
commit
c60bca777f
@ -25,7 +25,8 @@
|
||||
"suspicious": {
|
||||
"noExplicitAny": "off",
|
||||
"noExtraNonNullAssertion": "off",
|
||||
"noRedeclare": "off"
|
||||
"noRedeclare": "off",
|
||||
"noPrototypeBuiltins": "off"
|
||||
}
|
||||
},
|
||||
"ignore": [
|
||||
|
@ -110,7 +110,6 @@
|
||||
"express-rate-limit": "^6.6.0",
|
||||
"express-session": "^1.17.1",
|
||||
"fast-json-patch": "^3.1.0",
|
||||
"gravatar-url": "^3.1.0",
|
||||
"hash-sum": "^2.0.0",
|
||||
"helmet": "^6.0.0",
|
||||
"http-errors": "^2.0.0",
|
||||
|
@ -531,11 +531,10 @@ export class FeatureEventFormatterMd implements FeatureEventFormatter {
|
||||
SEMVER_LT: 'is a SemVer less than',
|
||||
};
|
||||
const formatConstraint = (constraint: IConstraint) => {
|
||||
const val = Object.hasOwn(constraint, 'value')
|
||||
const val = constraint.hasOwnProperty('value')
|
||||
? constraint.value
|
||||
: `(${constraint.values?.join(',')})`;
|
||||
const operator = Object.hasOwn(
|
||||
constraintOperatorDescriptions,
|
||||
const operator = constraintOperatorDescriptions.hasOwnProperty(
|
||||
constraint.operator,
|
||||
)
|
||||
? constraintOperatorDescriptions[constraint.operator]
|
||||
|
@ -1321,7 +1321,7 @@ class FeatureToggleService {
|
||||
if (
|
||||
replaceGroupId &&
|
||||
s.parameters &&
|
||||
Object.hasOwn(s.parameters, 'groupId')
|
||||
s.parameters.hasOwnProperty('groupId')
|
||||
) {
|
||||
s.parameters.groupId = newFeatureName;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ test('should create user', () => {
|
||||
expect(user.name).toBe('ole');
|
||||
expect(user.email).toBe('some@email.com');
|
||||
expect(user.imageUrl).toBe(
|
||||
'https://gravatar.com/avatar/d8ffeba65ee5baf57e4901690edc8e1b?size=42&default=retro',
|
||||
'https://gravatar.com/avatar/676212ff796c79a3c06261eb10e3f455aa93998ee6e45263da13679c74b1e674?s=42&d=retro&r=g',
|
||||
);
|
||||
});
|
||||
|
||||
@ -20,7 +20,7 @@ test('should create user, all fields', () => {
|
||||
expect(user.username).toBe('admin');
|
||||
expect(user.email).toBe('some@email.com');
|
||||
expect(user.imageUrl).toBe(
|
||||
'https://gravatar.com/avatar/d8ffeba65ee5baf57e4901690edc8e1b?size=42&default=retro',
|
||||
'https://gravatar.com/avatar/676212ff796c79a3c06261eb10e3f455aa93998ee6e45263da13679c74b1e674?s=42&d=retro&r=g',
|
||||
);
|
||||
});
|
||||
|
||||
@ -47,7 +47,7 @@ test('Should create user with only username defined', () => {
|
||||
const user = new User({ id: 133, username: 'some-user' });
|
||||
expect(user.username).toBe('some-user');
|
||||
expect(user.imageUrl).toBe(
|
||||
'https://gravatar.com/avatar/140fd5a002fb8d728a9848f8c9fcea2a?size=42&default=retro',
|
||||
'https://gravatar.com/avatar/7e90ac329986624ba9929659913354473c6f965d5b559704409e3f933c0643b7?s=42&d=retro&r=g',
|
||||
);
|
||||
});
|
||||
|
||||
|
21
src/lib/util/generateImageUrl.test.ts
Normal file
21
src/lib/util/generateImageUrl.test.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { generateImageUrl } from './generateImageUrl';
|
||||
|
||||
describe('Gravatar image url', () => {
|
||||
it('generates the correct sha-256 hash for gravatars test idents', () => {
|
||||
expect(generateImageUrl({ email: 'MyEmailAddress@example.com' })).toBe(
|
||||
'https://gravatar.com/avatar/84059b07d4be67b806386c0aad8070a23f18836bbaae342275dc0a83414c32ee?s=42&d=retro&r=g',
|
||||
);
|
||||
});
|
||||
it('lowercases and trims all emails', () => {
|
||||
const upperCaseAndLeadingSpace = ' helloWorld@example.com';
|
||||
const upperCaseAndTrailingSpace = 'helloWorld@exAMPLE.com ';
|
||||
const lowerCaseAndNoSpaces = 'helloworld@example.com';
|
||||
const uCALSHash = generateImageUrl({ email: upperCaseAndLeadingSpace });
|
||||
const uCATSHash = generateImageUrl({
|
||||
email: upperCaseAndTrailingSpace,
|
||||
});
|
||||
const lCANSHash = generateImageUrl({ email: lowerCaseAndNoSpaces });
|
||||
expect(uCALSHash).toBe(uCATSHash);
|
||||
expect(uCATSHash).toBe(lCANSHash);
|
||||
});
|
||||
});
|
@ -1,11 +1,17 @@
|
||||
import gravatarUrl from 'gravatar-url';
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
const base: string = 'https://gravatar.com/avatar';
|
||||
export const generateImageUrl = (user: {
|
||||
email: string;
|
||||
username: string;
|
||||
id: number;
|
||||
}): string =>
|
||||
gravatarUrl(user.email || user.username || String(user.id), {
|
||||
size: 42,
|
||||
default: 'retro',
|
||||
});
|
||||
email?: string;
|
||||
username?: string;
|
||||
id?: number;
|
||||
}): string => {
|
||||
let ident = user.email || user.username || String(user.id);
|
||||
if (ident.indexOf('@')) {
|
||||
ident = ident.toLowerCase().trim();
|
||||
} else {
|
||||
ident = ident.trim();
|
||||
}
|
||||
const identHash = createHash('sha256').update(ident).digest('hex');
|
||||
return `${base}/${identHash}?s=42&d=retro&r=g`;
|
||||
};
|
||||
|
25
yarn.lock
25
yarn.lock
@ -1859,11 +1859,6 @@ bluebird@^3.1.1, bluebird@^3.7.2:
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||
|
||||
blueimp-md5@^2.10.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.19.0.tgz#b53feea5498dcb53dc6ec4b823adb84b729c4af0"
|
||||
integrity sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==
|
||||
|
||||
body-parser@1.20.1:
|
||||
version "1.20.1"
|
||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
|
||||
@ -3384,14 +3379,6 @@ graceful-fs@^4.2.10, graceful-fs@^4.2.9:
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
|
||||
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
||||
|
||||
gravatar-url@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/gravatar-url/-/gravatar-url-3.1.0.tgz#0cbeedab7c00a7bc9b627b3716e331359efcc999"
|
||||
integrity sha512-+lOs7Rz1A051OqdqE8Tm4lmeyVgkqH8c6ll5fv///ncdIaL+XnOFmKAB70ix1du/yj8c3EWKbP6OhKjihsBSfA==
|
||||
dependencies:
|
||||
md5-hex "^3.0.1"
|
||||
type-fest "^0.8.1"
|
||||
|
||||
har-schema@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
@ -4684,13 +4671,6 @@ map-stream@~0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
|
||||
integrity sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==
|
||||
|
||||
md5-hex@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-3.0.1.tgz#be3741b510591434b2784d79e556eefc2c9a8e5c"
|
||||
integrity sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==
|
||||
dependencies:
|
||||
blueimp-md5 "^2.10.0"
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
@ -6631,11 +6611,6 @@ type-fest@^0.21.3:
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||
|
||||
type-fest@^0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
type-fest@^1.0.1, type-fest@^1.2.1, type-fest@^1.2.2:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1"
|
||||
|
Loading…
Reference in New Issue
Block a user