mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into 2473-feature-emails-further-design-of-html-emails
This commit is contained in:
commit
80b742f6cd
@ -25,10 +25,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
node: true,
|
node: true,
|
||||||
},
|
},
|
||||||
|
// the parser cannot handle the split sodium import
|
||||||
|
'import/ignore': ['sodium-native'],
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'no-console': 'error',
|
'no-console': 'error',
|
||||||
camelcase: ['error', { allow: ['FederationClient_*'] }],
|
camelcase: ['error', { allow: ['FederationClient_*', 'crypto_*', 'randombytes_random'] }],
|
||||||
'no-debugger': 'error',
|
'no-debugger': 'error',
|
||||||
'prettier/prettier': [
|
'prettier/prettier': [
|
||||||
'error',
|
'error',
|
||||||
@ -58,7 +60,10 @@ module.exports = {
|
|||||||
'import/no-dynamic-require': 'error',
|
'import/no-dynamic-require': 'error',
|
||||||
'import/no-internal-modules': 'off',
|
'import/no-internal-modules': 'off',
|
||||||
'import/no-relative-packages': 'error',
|
'import/no-relative-packages': 'error',
|
||||||
'import/no-relative-parent-imports': ['error', { ignore: ['@/*', 'random-bigint'] }],
|
'import/no-relative-parent-imports': [
|
||||||
|
'error',
|
||||||
|
{ ignore: ['@/*', 'random-bigint', 'sodium-native'] },
|
||||||
|
],
|
||||||
'import/no-self-import': 'error',
|
'import/no-self-import': 'error',
|
||||||
'import/no-unresolved': 'error',
|
'import/no-unresolved': 'error',
|
||||||
'import/no-useless-path-segments': 'error',
|
'import/no-useless-path-segments': 'error',
|
||||||
|
|||||||
8
backend/@types/sodium-native/index.d.ts
vendored
Normal file
8
backend/@types/sodium-native/index.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// eslint-disable-next-line import/no-unresolved
|
||||||
|
export * from '@/node_modules/@types/sodium-native'
|
||||||
|
|
||||||
|
declare module 'sodium-native' {
|
||||||
|
export function crypto_hash_sha512_init(state: Buffer, key?: Buffer, outlen?: Buffer): void
|
||||||
|
export function crypto_hash_sha512_update(state: Buffer, input: Buffer): void
|
||||||
|
export function crypto_hash_sha512_final(state: Buffer, out: Buffer): void
|
||||||
|
}
|
||||||
@ -55,6 +55,7 @@
|
|||||||
"@types/lodash.clonedeep": "^4.5.6",
|
"@types/lodash.clonedeep": "^4.5.6",
|
||||||
"@types/node": "^16.10.3",
|
"@types/node": "^16.10.3",
|
||||||
"@types/nodemailer": "^6.4.4",
|
"@types/nodemailer": "^6.4.4",
|
||||||
|
"@types/sodium-native": "^2.3.5",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
||||||
"@typescript-eslint/parser": "^5.57.1",
|
"@typescript-eslint/parser": "^5.57.1",
|
||||||
|
|||||||
@ -71,15 +71,13 @@ import { hasElopageBuys } from '@/util/hasElopageBuys'
|
|||||||
import { getTimeDurationObject, printTimeDuration } from '@/util/time'
|
import { getTimeDurationObject, printTimeDuration } from '@/util/time'
|
||||||
|
|
||||||
import random from 'random-bigint'
|
import random from 'random-bigint'
|
||||||
|
import { randombytes_random } from 'sodium-native'
|
||||||
|
|
||||||
import { FULL_CREATION_AVAILABLE } from './const/const'
|
import { FULL_CREATION_AVAILABLE } from './const/const'
|
||||||
import { getUserCreations } from './util/creations'
|
import { getUserCreations } from './util/creations'
|
||||||
import { findUserByIdentifier } from './util/findUserByIdentifier'
|
import { findUserByIdentifier } from './util/findUserByIdentifier'
|
||||||
import { validateAlias } from './util/validateAlias'
|
import { validateAlias } from './util/validateAlias'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-commonjs
|
|
||||||
const sodium = require('sodium-native')
|
|
||||||
|
|
||||||
const LANGUAGES = ['de', 'en', 'es', 'fr', 'nl']
|
const LANGUAGES = ['de', 'en', 'es', 'fr', 'nl']
|
||||||
const DEFAULT_LANGUAGE = 'de'
|
const DEFAULT_LANGUAGE = 'de'
|
||||||
const isLanguage = (language: string): boolean => {
|
const isLanguage = (language: string): boolean => {
|
||||||
@ -237,7 +235,7 @@ export class UserResolver {
|
|||||||
// TODO: this is unsecure, but the current implementation of the login server. This way it can be queried if the user with given EMail is existent.
|
// TODO: this is unsecure, but the current implementation of the login server. This way it can be queried if the user with given EMail is existent.
|
||||||
|
|
||||||
const user = new User(communityDbUser)
|
const user = new User(communityDbUser)
|
||||||
user.id = sodium.randombytes_random() % (2048 * 16) // TODO: for a better faking derive id from email so that it will be always the same id when the same email comes in?
|
user.id = randombytes_random() % (2048 * 16) // TODO: for a better faking derive id from email so that it will be always the same id when the same email comes in?
|
||||||
user.gradidoID = uuidv4()
|
user.gradidoID = uuidv4()
|
||||||
user.firstName = firstName
|
user.firstName = firstName
|
||||||
user.lastName = lastName
|
user.lastName = lastName
|
||||||
|
|||||||
@ -10,8 +10,19 @@ import { CONFIG } from '@/config'
|
|||||||
import { LogError } from '@/server/LogError'
|
import { LogError } from '@/server/LogError'
|
||||||
import { backendLogger as logger } from '@/server/logger'
|
import { backendLogger as logger } from '@/server/logger'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-commonjs
|
import {
|
||||||
const sodium = require('sodium-native')
|
crypto_shorthash_KEYBYTES,
|
||||||
|
crypto_box_SEEDBYTES,
|
||||||
|
crypto_hash_sha512_init,
|
||||||
|
crypto_hash_sha512_update,
|
||||||
|
crypto_hash_sha512_final,
|
||||||
|
crypto_hash_sha512_BYTES,
|
||||||
|
crypto_hash_sha512_STATEBYTES,
|
||||||
|
crypto_shorthash_BYTES,
|
||||||
|
crypto_pwhash_SALTBYTES,
|
||||||
|
crypto_pwhash,
|
||||||
|
crypto_shorthash,
|
||||||
|
} from 'sodium-native'
|
||||||
|
|
||||||
// We will reuse this for changePassword
|
// We will reuse this for changePassword
|
||||||
export const isValidPassword = (password: string): boolean => {
|
export const isValidPassword = (password: string): boolean => {
|
||||||
@ -22,36 +33,36 @@ export const SecretKeyCryptographyCreateKey = (salt: string, password: string):
|
|||||||
logger.trace('SecretKeyCryptographyCreateKey...')
|
logger.trace('SecretKeyCryptographyCreateKey...')
|
||||||
const configLoginAppSecret = Buffer.from(CONFIG.LOGIN_APP_SECRET, 'hex')
|
const configLoginAppSecret = Buffer.from(CONFIG.LOGIN_APP_SECRET, 'hex')
|
||||||
const configLoginServerKey = Buffer.from(CONFIG.LOGIN_SERVER_KEY, 'hex')
|
const configLoginServerKey = Buffer.from(CONFIG.LOGIN_SERVER_KEY, 'hex')
|
||||||
if (configLoginServerKey.length !== sodium.crypto_shorthash_KEYBYTES) {
|
if (configLoginServerKey.length !== crypto_shorthash_KEYBYTES) {
|
||||||
throw new LogError(
|
throw new LogError(
|
||||||
'ServerKey has an invalid size',
|
'ServerKey has an invalid size',
|
||||||
configLoginServerKey.length,
|
configLoginServerKey.length,
|
||||||
sodium.crypto_shorthash_KEYBYTES,
|
crypto_shorthash_KEYBYTES,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES)
|
const state = Buffer.alloc(crypto_hash_sha512_STATEBYTES)
|
||||||
sodium.crypto_hash_sha512_init(state)
|
crypto_hash_sha512_init(state)
|
||||||
sodium.crypto_hash_sha512_update(state, Buffer.from(salt))
|
crypto_hash_sha512_update(state, Buffer.from(salt))
|
||||||
sodium.crypto_hash_sha512_update(state, configLoginAppSecret)
|
crypto_hash_sha512_update(state, configLoginAppSecret)
|
||||||
const hash = Buffer.alloc(sodium.crypto_hash_sha512_BYTES)
|
const hash = Buffer.alloc(crypto_hash_sha512_BYTES)
|
||||||
sodium.crypto_hash_sha512_final(state, hash)
|
crypto_hash_sha512_final(state, hash)
|
||||||
|
|
||||||
const encryptionKey = Buffer.alloc(sodium.crypto_box_SEEDBYTES)
|
const encryptionKey = Buffer.alloc(crypto_box_SEEDBYTES)
|
||||||
const opsLimit = 10
|
const opsLimit = 10
|
||||||
const memLimit = 33554432
|
const memLimit = 33554432
|
||||||
const algo = 2
|
const algo = 2
|
||||||
sodium.crypto_pwhash(
|
crypto_pwhash(
|
||||||
encryptionKey,
|
encryptionKey,
|
||||||
Buffer.from(password),
|
Buffer.from(password),
|
||||||
hash.slice(0, sodium.crypto_pwhash_SALTBYTES),
|
hash.slice(0, crypto_pwhash_SALTBYTES),
|
||||||
opsLimit,
|
opsLimit,
|
||||||
memLimit,
|
memLimit,
|
||||||
algo,
|
algo,
|
||||||
)
|
)
|
||||||
|
|
||||||
const encryptionKeyHash = Buffer.alloc(sodium.crypto_shorthash_BYTES)
|
const encryptionKeyHash = Buffer.alloc(crypto_shorthash_BYTES)
|
||||||
sodium.crypto_shorthash(encryptionKeyHash, encryptionKey, configLoginServerKey)
|
crypto_shorthash(encryptionKeyHash, encryptionKey, configLoginServerKey)
|
||||||
|
|
||||||
return [encryptionKeyHash, encryptionKey]
|
return [encryptionKeyHash, encryptionKey]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1181,6 +1181,13 @@
|
|||||||
"@types/mime" "^1"
|
"@types/mime" "^1"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/sodium-native@^2.3.5":
|
||||||
|
version "2.3.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/sodium-native/-/sodium-native-2.3.5.tgz#5d2681e7b6b67bcbdc63cfb133e303ec9e942e43"
|
||||||
|
integrity sha512-a3DAIpW8+36XAY8aIR36JBQQsfOabxHuJwx11DL/PTvnbwEWPAXW66b8QbMi0r2vUnkOfREsketxdvjBmQxqDQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/stack-utils@^2.0.0":
|
"@types/stack-utils@^2.0.0":
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
|
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
|
||||||
@ -3645,7 +3652,7 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
|||||||
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
||||||
|
|
||||||
"gradido-database@file:../database":
|
"gradido-database@file:../database":
|
||||||
version "1.20.0"
|
version "1.21.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/uuid" "^8.3.4"
|
"@types/uuid" "^8.3.4"
|
||||||
cross-env "^7.0.3"
|
cross-env "^7.0.3"
|
||||||
|
|||||||
@ -101,43 +101,43 @@ module.exports = {
|
|||||||
// ],
|
// ],
|
||||||
// 'import/prefer-default-export': 'off',
|
// 'import/prefer-default-export': 'off',
|
||||||
// n
|
// n
|
||||||
// 'n/handle-callback-err': 'error',
|
'n/handle-callback-err': 'error',
|
||||||
// 'n/no-callback-literal': 'error',
|
'n/no-callback-literal': 'error',
|
||||||
// 'n/no-exports-assign': 'error',
|
'n/no-exports-assign': 'error',
|
||||||
// 'n/no-extraneous-import': 'error',
|
// 'n/no-extraneous-import': 'error',
|
||||||
// 'n/no-extraneous-require': 'error',
|
'n/no-extraneous-require': 'error',
|
||||||
// 'n/no-hide-core-modules': 'error',
|
'n/no-hide-core-modules': 'error',
|
||||||
// 'n/no-missing-import': 'off', // not compatible with typescript
|
'n/no-missing-import': 'off', // not compatible with typescript
|
||||||
// 'n/no-missing-require': 'error',
|
'n/no-missing-require': 'error',
|
||||||
// 'n/no-new-require': 'error',
|
'n/no-new-require': 'error',
|
||||||
// 'n/no-path-concat': 'error',
|
'n/no-path-concat': 'error',
|
||||||
// 'n/no-process-exit': 'error',
|
// 'n/no-process-exit': 'error',
|
||||||
// 'n/no-unpublished-bin': 'error',
|
'n/no-unpublished-bin': 'error',
|
||||||
// 'n/no-unpublished-import': 'off', // TODO need to exclude seeds
|
'n/no-unpublished-import': 'off', // TODO need to exclude seeds
|
||||||
// 'n/no-unpublished-require': 'error',
|
'n/no-unpublished-require': 'error',
|
||||||
// 'n/no-unsupported-features': ['error', { ignores: ['modules'] }],
|
'n/no-unsupported-features': ['error', { ignores: ['modules'] }],
|
||||||
// 'n/no-unsupported-features/es-builtins': 'error',
|
'n/no-unsupported-features/es-builtins': 'error',
|
||||||
// 'n/no-unsupported-features/es-syntax': 'error',
|
'n/no-unsupported-features/es-syntax': 'error',
|
||||||
// 'n/no-unsupported-features/node-builtins': 'error',
|
'n/no-unsupported-features/node-builtins': 'error',
|
||||||
// 'n/process-exit-as-throw': 'error',
|
'n/process-exit-as-throw': 'error',
|
||||||
// 'n/shebang': 'error',
|
'n/shebang': 'error',
|
||||||
// 'n/callback-return': 'error',
|
'n/callback-return': 'error',
|
||||||
// 'n/exports-style': 'error',
|
'n/exports-style': 'error',
|
||||||
// 'n/file-extension-in-import': 'off',
|
'n/file-extension-in-import': 'off',
|
||||||
// 'n/global-require': 'error',
|
'n/global-require': 'error',
|
||||||
// 'n/no-mixed-requires': 'error',
|
'n/no-mixed-requires': 'error',
|
||||||
// 'n/no-process-env': 'error',
|
'n/no-process-env': 'error',
|
||||||
// 'n/no-restricted-import': 'error',
|
'n/no-restricted-import': 'error',
|
||||||
// 'n/no-restricted-require': 'error',
|
'n/no-restricted-require': 'error',
|
||||||
// 'n/no-sync': 'error',
|
// 'n/no-sync': 'error',
|
||||||
// 'n/prefer-global/buffer': 'error',
|
'n/prefer-global/buffer': 'error',
|
||||||
// 'n/prefer-global/console': 'error',
|
'n/prefer-global/console': 'error',
|
||||||
// 'n/prefer-global/process': 'error',
|
'n/prefer-global/process': 'error',
|
||||||
// 'n/prefer-global/text-decoder': 'error',
|
'n/prefer-global/text-decoder': 'error',
|
||||||
// 'n/prefer-global/text-encoder': 'error',
|
'n/prefer-global/text-encoder': 'error',
|
||||||
// 'n/prefer-global/url': 'error',
|
'n/prefer-global/url': 'error',
|
||||||
// 'n/prefer-global/url-search-params': 'error',
|
'n/prefer-global/url-search-params': 'error',
|
||||||
// 'n/prefer-promises/dns': 'error',
|
'n/prefer-promises/dns': 'error',
|
||||||
// 'n/prefer-promises/fs': 'error',
|
// 'n/prefer-promises/fs': 'error',
|
||||||
// promise
|
// promise
|
||||||
// 'promise/catch-or-return': 'error',
|
// 'promise/catch-or-return': 'error',
|
||||||
|
|||||||
@ -48,5 +48,8 @@
|
|||||||
"ts-mysql-migrate": "^1.0.2",
|
"ts-mysql-migrate": "^1.0.2",
|
||||||
"typeorm": "^0.2.38",
|
"typeorm": "^0.2.38",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env)
|
/* eslint-disable n/no-process-env */
|
||||||
|
|
||||||
import dotenv from 'dotenv'
|
import dotenv from 'dotenv'
|
||||||
dotenv.config()
|
dotenv.config()
|
||||||
|
|||||||
@ -24,6 +24,8 @@ type CommunityApi = {
|
|||||||
url: string
|
url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KeyPair = { publicKey: Buffer; secretKey: Buffer }
|
||||||
|
|
||||||
export const startDHT = async (topic: string): Promise<void> => {
|
export const startDHT = async (topic: string): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
const TOPIC = DHT.hash(Buffer.from(topic))
|
const TOPIC = DHT.hash(Buffer.from(topic))
|
||||||
@ -32,11 +34,11 @@ export const startDHT = async (topic: string): Promise<void> => {
|
|||||||
CONFIG.FEDERATION_DHT_SEED
|
CONFIG.FEDERATION_DHT_SEED
|
||||||
? Buffer.alloc(KEY_SECRET_SEEDBYTES, CONFIG.FEDERATION_DHT_SEED)
|
? Buffer.alloc(KEY_SECRET_SEEDBYTES, CONFIG.FEDERATION_DHT_SEED)
|
||||||
: null,
|
: null,
|
||||||
)
|
) as KeyPair
|
||||||
const pubKeyString = keyPair.publicKey.toString('hex')
|
const pubKeyString = keyPair.publicKey.toString('hex')
|
||||||
logger.info(`keyPairDHT: publicKey=${pubKeyString}`)
|
logger.info(`keyPairDHT: publicKey=${pubKeyString}`)
|
||||||
logger.debug(`keyPairDHT: secretKey=${keyPair.secretKey.toString('hex')}`)
|
logger.debug(`keyPairDHT: secretKey=${keyPair.secretKey.toString('hex')}`)
|
||||||
await writeHomeCommunityEntry(pubKeyString)
|
await writeHomeCommunityEntry(keyPair)
|
||||||
|
|
||||||
const ownApiVersions = await writeFederatedHomeCommunityEntries(pubKeyString)
|
const ownApiVersions = await writeFederatedHomeCommunityEntries(pubKeyString)
|
||||||
logger.info(`ApiList: ${JSON.stringify(ownApiVersions)}`)
|
logger.info(`ApiList: ${JSON.stringify(ownApiVersions)}`)
|
||||||
@ -212,13 +214,13 @@ async function writeFederatedHomeCommunityEntries(pubKey: string): Promise<Commu
|
|||||||
return homeApiVersions
|
return homeApiVersions
|
||||||
}
|
}
|
||||||
|
|
||||||
async function writeHomeCommunityEntry(pubKey: string): Promise<void> {
|
async function writeHomeCommunityEntry(keyPair: KeyPair): Promise<void> {
|
||||||
try {
|
try {
|
||||||
// check for existing homeCommunity entry
|
// check for existing homeCommunity entry
|
||||||
let homeCom = await DbCommunity.findOne({ foreign: false })
|
let homeCom = await DbCommunity.findOne({ foreign: false })
|
||||||
if (homeCom) {
|
if (homeCom) {
|
||||||
// simply update the existing entry, but it MUST keep the ID and UUID because of possible relations
|
// simply update the existing entry, but it MUST keep the ID and UUID because of possible relations
|
||||||
homeCom.publicKey = Buffer.from(pubKey)
|
homeCom.publicKey = keyPair.publicKey
|
||||||
homeCom.url = CONFIG.FEDERATION_COMMUNITY_URL + '/api/'
|
homeCom.url = CONFIG.FEDERATION_COMMUNITY_URL + '/api/'
|
||||||
homeCom.name = CONFIG.COMMUNITY_NAME
|
homeCom.name = CONFIG.COMMUNITY_NAME
|
||||||
homeCom.description = CONFIG.COMMUNITY_DESCRIPTION
|
homeCom.description = CONFIG.COMMUNITY_DESCRIPTION
|
||||||
@ -228,7 +230,7 @@ async function writeHomeCommunityEntry(pubKey: string): Promise<void> {
|
|||||||
// insert a new homecommunity entry including a new ID and a new but ensured unique UUID
|
// insert a new homecommunity entry including a new ID and a new but ensured unique UUID
|
||||||
homeCom = new DbCommunity()
|
homeCom = new DbCommunity()
|
||||||
homeCom.foreign = false
|
homeCom.foreign = false
|
||||||
homeCom.publicKey = Buffer.from(pubKey)
|
homeCom.publicKey = keyPair.publicKey
|
||||||
homeCom.communityUuid = await newCommunityUuid()
|
homeCom.communityUuid = await newCommunityUuid()
|
||||||
homeCom.url = CONFIG.FEDERATION_COMMUNITY_URL + '/api/'
|
homeCom.url = CONFIG.FEDERATION_COMMUNITY_URL + '/api/'
|
||||||
homeCom.name = CONFIG.COMMUNITY_NAME
|
homeCom.name = CONFIG.COMMUNITY_NAME
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user