From 1de1187452f9104e85d9526c4bf80a6aeebf7e27 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sun, 31 Oct 2021 04:58:21 +0100 Subject: [PATCH 01/47] corrected model to utilize Node10 BigInt --- database/entity/0003-login_server_tables/LoginUser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/entity/0003-login_server_tables/LoginUser.ts b/database/entity/0003-login_server_tables/LoginUser.ts index 26614b4db..1b444b0e4 100644 --- a/database/entity/0003-login_server_tables/LoginUser.ts +++ b/database/entity/0003-login_server_tables/LoginUser.ts @@ -22,7 +22,7 @@ export class LoginUser extends BaseEntity { description: string @Column({ type: 'bigint', default: 0, unsigned: true }) - password: string + password: BigInt @Column({ name: 'pubkey', type: 'binary', length: 32, default: null, nullable: true }) pubKey: Buffer From 77d89d55dbb6e7fd1011474b9e911aaca3a4311a Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sun, 31 Oct 2021 04:59:07 +0100 Subject: [PATCH 02/47] implemented create user in apollo - Pubkey generation still missing --- backend/src/graphql/resolver/UserResolver.ts | 127 ++++++++++++++++--- 1 file changed, 108 insertions(+), 19 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f6eccd7e8..6fbf60c7a 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -27,6 +27,39 @@ import { Setting } from '../enum/Setting' import { UserRepository } from '../../typeorm/repository/User' import { LoginUser } from '@entity/LoginUser' +// We will reuse this for changePassword +const isPassword = (password: string): boolean => { + if (!password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9 \\t\\n\\r]).{8,}$/)) { + return false + // TODO we dont need this right, frontend does it? + /* + if(pwd.length < 8){ + throw new Error('Your password is to short!') + } + if(!pwd.match(/[a-z]/)){ + throw new Error('Your password does not contain lowercase letters!') + } + if(!pwd.match(/[A-Z]/)){ + throw new Error('Your password does not contain any capital letters!') + } + if(!pwd.match(/[0-9]/)){ + throw new Error('Your password does not contain any number!') + } + if(!pwd.match(/[^a-zA-Z0-9 \\t\\n\\r]/)){ + throw new Error('Your password does not contain special characters!') + } + */ + } + return true +} + +const LANGUAGES = ['de', 'en'] +const DEFAULT_LANGUAGE = 'de' +// very likely to be reused +const isLanguage = (language: string): boolean => { + return LANGUAGES.includes(language) +} + @Resolver() export class UserResolver { @Query(() => User) @@ -121,28 +154,84 @@ export class UserResolver { async createUser( @Args() { email, firstName, lastName, password, language, publisherId }: CreateUserArgs, ): Promise { - const payload = { - email, - first_name: firstName, - last_name: lastName, - password, - emailType: 2, - login_after_register: true, - language: language, - publisher_id: publisherId, - } - const result = await apiPost(CONFIG.LOGIN_API_URL + 'createUser', payload) - if (!result.success) { - throw new Error(result.data) + const username = '' + + // TODO: wrong default value (should be null), how does graphql work here? Is it an required field? + // default int publisher_id = 0; + + // Validate Language (no throw) + if (!isLanguage(language)) { + language = DEFAULT_LANGUAGE } - const user = new User(result.data.user) + // Validate Password + // TODO Login Server ignored this when he got an empty password?! + if (!isPassword(password)) { + throw new Error( + 'Please enter a valid password with at least 8 characters, upper and lower case letters, at least one number and one special character!', + ) + } + + // Validate username + // TODO: never true + if (username.length > 3 && !this.checkUsername({ username })) { + throw new Error('Username already in use') + } + + // Validate email unique + // TODO: i can register an email in upper/lower case twice + const usersFound = await LoginUser.count({ email }) + if (usersFound !== 0) { + // 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. + throw new Error(`User already exists.`) + } + + const loginUser = new LoginUser() + loginUser.email = email + loginUser.firstName = firstName + loginUser.lastName = lastName + loginUser.username = username + loginUser.description = '' + loginUser.password = BigInt(0) + // TODO: This was never used according to my analysis. Therefore I consider it safe to set to 0 + loginUser.emailHash = Buffer.from([0]) + loginUser.language = language + loginUser.groupId = 1 + loginUser.publisherId = publisherId + + // TODO: check if this insert method is correct, we had problems with that! + loginUser.save().catch(() => { + // TODO: this triggered an EMail send + throw new Error('insert user failed') + }) + + // TODO: pubkey + // session->generateKeys(true, true); + + // TODO: we do not login the user as before, since session management is not yet ported + // calculate encryption key, could need some time, will save encrypted privkey to db + // UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(user, password); + // create_authenticated_encrypten_key->scheduleTask(create_authenticated_encrypten_key); + + // TODO: send EMail (EMAIL_OPT_IN_REGISTER) + // const emailType = 2 + // auto emailOptIn = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); + // auto emailOptInModel = emailOptIn->getModel(); + // if (!emailOptInModel->insertIntoDB(false)) { + // emailOptInModel->sendErrorsAsEmail(); + // return stateError("insert emailOptIn failed"); + // } + // emailOptIn->setBaseUrl(user->getGroupBaseUrl() + ServerConfig::g_frontend_checkEmailPath); + // em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); + + // ------------------------------------------------------ + const dbuser = new DbUser() - dbuser.pubkey = Buffer.from(fromHex(user.pubkey)) - dbuser.email = user.email - dbuser.firstName = user.firstName - dbuser.lastName = user.lastName - dbuser.username = user.username + dbuser.pubkey = Buffer.from(fromHex(pubkey)) + dbuser.email = email + dbuser.firstName = firstName + dbuser.lastName = lastName + dbuser.username = username dbuser.save().catch(() => { throw new Error('error saving user') From 148ba6e0aee3ab6aa52169ae46e784030dc053d2 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sun, 31 Oct 2021 23:54:26 +0100 Subject: [PATCH 03/47] LoginUserBackup typeorm entity definition --- .../0003-login_server_tables/LoginUserBackup.ts | 16 ++++++++++++++++ database/entity/LoginUserBackup.ts | 1 + database/entity/index.ts | 2 ++ 3 files changed, 19 insertions(+) create mode 100644 database/entity/0003-login_server_tables/LoginUserBackup.ts create mode 100644 database/entity/LoginUserBackup.ts diff --git a/database/entity/0003-login_server_tables/LoginUserBackup.ts b/database/entity/0003-login_server_tables/LoginUserBackup.ts new file mode 100644 index 000000000..af152e534 --- /dev/null +++ b/database/entity/0003-login_server_tables/LoginUserBackup.ts @@ -0,0 +1,16 @@ +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm' + +@Entity('login_user_backups') +export class LoginUserBackup extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ name: 'user_id', nullable: false }) + userId: number + + @Column({ type: 'text', name: 'passphrase', nullable: false }) + passphrase: string + + @Column({ name: 'mnemonic_type', default: -1 }) + mnemonicType: number +} diff --git a/database/entity/LoginUserBackup.ts b/database/entity/LoginUserBackup.ts new file mode 100644 index 000000000..23d2c9271 --- /dev/null +++ b/database/entity/LoginUserBackup.ts @@ -0,0 +1 @@ +export { LoginUserBackup } from './0003-login_server_tables/LoginUserBackup' diff --git a/database/entity/index.ts b/database/entity/index.ts index 1881b2932..da6761da2 100644 --- a/database/entity/index.ts +++ b/database/entity/index.ts @@ -1,5 +1,6 @@ import { Balance } from './Balance' import { LoginUser } from './LoginUser' +import { LoginUserBackup } from './LoginUserBackup' import { Migration } from './Migration' import { Transaction } from './Transaction' import { TransactionCreation } from './TransactionCreation' @@ -11,6 +12,7 @@ import { UserTransaction } from './UserTransaction' export const entities = [ Balance, LoginUser, + LoginUserBackup, Migration, Transaction, TransactionCreation, From c48992131324c4de77bf97adcacabef62b99444f Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sun, 31 Oct 2021 23:55:33 +0100 Subject: [PATCH 04/47] - removed libsodium-wrappers and installed sodium-native since we need the esoteric functions aswell - added conversion library from bigint to buffer --- backend/package.json | 7 ++++--- backend/yarn.lock | 48 ++++++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/backend/package.json b/backend/package.json index 889143ac3..c3fec6983 100644 --- a/backend/package.json +++ b/backend/package.json @@ -19,6 +19,7 @@ "@types/jest": "^27.0.2", "apollo-server-express": "^2.25.2", "axios": "^0.21.1", + "bigint-conversion": "^2.2.1", "class-validator": "^0.13.1", "cors": "^2.8.5", "dotenv": "^10.0.0", @@ -26,10 +27,10 @@ "graphql": "^15.5.1", "jest": "^27.2.4", "jsonwebtoken": "^8.5.1", - "libsodium-wrappers": "^0.7.9", "module-alias": "^2.2.2", "mysql2": "^2.3.0", "reflect-metadata": "^0.1.13", + "sodium-native": "^3.3.0", "ts-jest": "^27.0.5", "type-graphql": "^1.1.1", "typeorm": "^0.2.38" @@ -37,7 +38,7 @@ "devDependencies": { "@types/express": "^4.17.12", "@types/jsonwebtoken": "^8.5.2", - "@types/libsodium-wrappers": "^0.7.9", + "@types/sodium-native": "^2.3.5", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", "eslint": "^7.29.0", @@ -53,6 +54,6 @@ "typescript": "^4.3.4" }, "_moduleAliases": { - "@entity" : "../database/build/entity" + "@entity": "../database/build/entity" } } diff --git a/backend/yarn.lock b/backend/yarn.lock index 373f623f0..92c679039 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -562,6 +562,11 @@ resolved "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz" integrity sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg== +"@juanelas/base64@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@juanelas/base64/-/base64-1.0.1.tgz#aaede00ffdca595741fc69d0008b4cfc8f08293a" + integrity sha512-ZK/wWrjMrrMcprtOV72iilC1M/HfZcF2JeUJPHOL0tMm1TZrh9UhHDQEdPny/MmmT7tO4w47ycuy0YTnBrS5fg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -888,11 +893,6 @@ "@types/koa-compose" "*" "@types/node" "*" -"@types/libsodium-wrappers@^0.7.9": - version "0.7.9" - resolved "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz" - integrity sha512-LisgKLlYQk19baQwjkBZZXdJL0KbeTpdEnrAfz5hQACbklCY0gVFnsKUyjfNWF1UQsCSjw93Sj5jSbiO8RPfdw== - "@types/long@^4.0.0": version "4.0.1" resolved "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz" @@ -951,6 +951,13 @@ "@types/mime" "^1" "@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": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -1512,6 +1519,13 @@ base64-js@^1.3.1: resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bigint-conversion@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/bigint-conversion/-/bigint-conversion-2.2.1.tgz#08c9f17a826943c7e56d4bfa9f0fc7fe8050a940" + integrity sha512-9TvqpV+VZ04fPKv4KPLQRk5ZAFhgHX4F7bYQY263/BbJBFzEGbtBeTQV9oNuAGaqj88PXdov1OcSNQtq9K9MPA== + dependencies: + "@juanelas/base64" "^1.0.1" + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" @@ -3871,18 +3885,6 @@ libphonenumber-js@^1.9.7: resolved "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.9.22.tgz" integrity sha512-nE0aF0wrNq09ewF36s9FVqRW73hmpw6cobVDlbexmsu1432LEfuN24BCudNuRx4t2rElSeK/N0JbedzRW/TC4A== -libsodium-wrappers@^0.7.9: - version "0.7.9" - resolved "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz" - integrity sha512-9HaAeBGk1nKTRFRHkt7nzxqCvnkWTjn1pdjKgcUnZxj0FyOP4CnhgFhMdrFfgNsukijBGyBLpP2m2uKT1vuWhQ== - dependencies: - libsodium "^0.7.0" - -libsodium@^0.7.0: - version "0.7.9" - resolved "https://registry.npmjs.org/libsodium/-/libsodium-0.7.9.tgz" - integrity sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A== - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz" @@ -4186,6 +4188,11 @@ node-fetch@^2.6.1: resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-gyp-build@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4910,6 +4917,13 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +sodium-native@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/sodium-native/-/sodium-native-3.3.0.tgz#50ee52ac843315866cce3d0c08ab03eb78f22361" + integrity sha512-rg6lCDM/qa3p07YGqaVD+ciAbUqm6SoO4xmlcfkbU5r1zIGrguXztLiEtaLYTV5U6k8KSIUFmnU3yQUSKmf6DA== + dependencies: + node-gyp-build "^4.3.0" + source-map-support@^0.5.17: version "0.5.19" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz" From a9e16708a48992f4425449cb95d2e9f7b019172a Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sun, 31 Oct 2021 23:57:11 +0100 Subject: [PATCH 05/47] implemented: - PassphraseGenerate - KeyPairEd25519Create - generateKeys for createUser in order to generate the privateKeys (unoptimized) --- backend/src/graphql/resolver/UserResolver.ts | 118 +++++++++++++++++-- 1 file changed, 110 insertions(+), 8 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 6fbf60c7a..8089fc677 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -1,9 +1,19 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +import fs from 'fs' import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql' -import { from_hex as fromHex } from 'libsodium-wrappers' -import { getCustomRepository } from 'typeorm' +import { + /* eslint-disable camelcase */ + randombytes_random, + crypto_hash_sha512_instance, + crypto_hash_sha512_BYTES, + crypto_sign_seed_keypair, + crypto_sign_PUBLICKEYBYTES, + crypto_sign_SECRETKEYBYTES, + /* eslint-enable camelcase */ +} from 'sodium-native' +import { getCustomRepository, NoNeedToReleaseEntityManagerError } from 'typeorm' import CONFIG from '../../config' import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode' import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse' @@ -26,6 +36,8 @@ import { UserSettingRepository } from '../../typeorm/repository/UserSettingRepos import { Setting } from '../enum/Setting' import { UserRepository } from '../../typeorm/repository/User' import { LoginUser } from '@entity/LoginUser' +import { LoginUserBackup } from '@entity/LoginUserBackup' +import { bigintToBuf } from 'bigint-conversion' // We will reuse this for changePassword const isPassword = (password: string): boolean => { @@ -60,6 +72,96 @@ const isLanguage = (language: string): boolean => { return LANGUAGES.includes(language) } +const PHRASE_WORD_COUNT = 24 +const WORDS = fs.readFileSync('src/config/mnemonic.english.txt').toString().split('\n') +const PassphraseGenerate = (): string[] => { + const result = [] + for (let i = 0; i < PHRASE_WORD_COUNT; i++) { + result.push(WORDS[randombytes_random() % 2048]) + } + return result +} + +const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { + if (!passphrase.length) { + throw new Error('passphrase empty') + } + + const wordIndicies = [] + for (let i = 0; i < PHRASE_WORD_COUNT; i++) { + wordIndicies.push(WORDS.indexOf(passphrase[i])) + } + + // TODO: wtf is this? + // if (!wordIndicies || (!wordIndicies[0] && !wordIndicies[1] && !wordIndicies[2] && !wordIndicies[3])) { + // return null; + // } + const clearPassphrase = passphrase.join(' ') + + // Assuming this calls `crypto_hash_sha512_init` + const hash = crypto_hash_sha512_instance() + + // **** convert word indices into uint64 **** + // To prevent breaking existing passphrase-hash combinations word indices will be put into 64 Bit Variable to mimic first implementation of algorithms + for (let i = 0; i < PHRASE_WORD_COUNT; i++) { + const value = BigInt(wordIndicies[i]) + hash.update(Buffer.from(bigintToBuf(value))) + } + // **** end converting into uint64 ***** + hash.update(Buffer.from(clearPassphrase)) + const outputHashBuffer = Buffer.alloc(crypto_hash_sha512_BYTES) + hash.final(outputHashBuffer) + + const pubKey = Buffer.alloc(crypto_sign_PUBLICKEYBYTES) + const privKey = Buffer.alloc(crypto_sign_SECRETKEYBYTES) + + crypto_sign_seed_keypair(pubKey, privKey, outputHashBuffer) + + return [pubKey, privKey] +} + +const generateKeys = async ( + email: string, + savePrivkey: boolean, + savePassphrase: boolean, +): Promise => { + const mNewUser = await LoginUser.findOneOrFail({ email }) + const lang = mNewUser.language + /* + if (LANG_DE == lang) { + mnemonic_type = ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES; + } + */ + + const passphrase = PassphraseGenerate() + + if (savePassphrase) { + const loginUserBackup = new LoginUserBackup() + loginUserBackup.userId = mNewUser.id + loginUserBackup.passphrase = passphrase.join(' ') + loginUserBackup.mnemonicType = 2 // ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; + + await loginUserBackup.save().catch(() => { + throw new Error('insert user backup failed') + }) + } + + // keys + const gradidoKeyPair = KeyPairEd25519Create(passphrase) + + mNewUser.pubKey = gradidoKeyPair[0] + + if (savePrivkey) { + mNewUser.privKey = gradidoKeyPair[1] + } + + await mNewUser.save().catch(() => { + throw new Error(`Error saving new generated pub/priv keys, email: ${email}`) + }) + + return gradidoKeyPair +} + @Resolver() export class UserResolver { @Query(() => User) @@ -95,7 +197,7 @@ export class UserResolver { userEntity.lastName = user.lastName userEntity.username = user.username userEntity.email = user.email - userEntity.pubkey = Buffer.from(fromHex(user.pubkey)) + userEntity.pubkey = Buffer.from(user.pubkey, 'hex') userEntity.save().catch(() => { throw new Error('error by save userEntity') @@ -200,13 +302,13 @@ export class UserResolver { loginUser.publisherId = publisherId // TODO: check if this insert method is correct, we had problems with that! - loginUser.save().catch(() => { + await loginUser.save().catch(() => { // TODO: this triggered an EMail send throw new Error('insert user failed') }) - // TODO: pubkey - // session->generateKeys(true, true); + const keys = await generateKeys(email, true, true) + const pubkey = keys[0] // TODO: we do not login the user as before, since session management is not yet ported // calculate encryption key, could need some time, will save encrypted privkey to db @@ -227,13 +329,13 @@ export class UserResolver { // ------------------------------------------------------ const dbuser = new DbUser() - dbuser.pubkey = Buffer.from(fromHex(pubkey)) + dbuser.pubkey = pubkey dbuser.email = email dbuser.firstName = firstName dbuser.lastName = lastName dbuser.username = username - dbuser.save().catch(() => { + await dbuser.save().catch(() => { throw new Error('error saving user') }) From 6dfb671b145b5b6888d5726b38c33c320edb4c78 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 1 Nov 2021 00:05:51 +0100 Subject: [PATCH 06/47] different mnemonic word lists. It is unclear which to use for what. --- backend/src/config/mnemonic.english.txt | 2048 +++++++++++++++++ backend/src/config/mnemonic.words_ulf.txt | 2048 +++++++++++++++++ backend/src/config/mnemonic.words_ulf_org.txt | 2048 +++++++++++++++++ 3 files changed, 6144 insertions(+) create mode 100644 backend/src/config/mnemonic.english.txt create mode 100644 backend/src/config/mnemonic.words_ulf.txt create mode 100644 backend/src/config/mnemonic.words_ulf_org.txt diff --git a/backend/src/config/mnemonic.english.txt b/backend/src/config/mnemonic.english.txt new file mode 100644 index 000000000..942040ed5 --- /dev/null +++ b/backend/src/config/mnemonic.english.txt @@ -0,0 +1,2048 @@ +abandon +ability +able +about +above +absent +absorb +abstract +absurd +abuse +access +accident +account +accuse +achieve +acid +acoustic +acquire +across +act +action +actor +actress +actual +adapt +add +addict +address +adjust +admit +adult +advance +advice +aerobic +affair +afford +afraid +again +age +agent +agree +ahead +aim +air +airport +aisle +alarm +album +alcohol +alert +alien +all +alley +allow +almost +alone +alpha +already +also +alter +always +amateur +amazing +among +amount +amused +analyst +anchor +ancient +anger +angle +angry +animal +ankle +announce +annual +another +answer +antenna +antique +anxiety +any +apart +apology +appear +apple +approve +april +arch +arctic +area +arena +argue +arm +armed +armor +army +around +arrange +arrest +arrive +arrow +art +artefact +artist +artwork +ask +aspect +assault +asset +assist +assume +asthma +athlete +atom +attack +attend +attitude +attract +auction +audit +august +aunt +author +auto +autumn +average +avocado +avoid +awake +aware +away +awesome +awful +awkward +axis +baby +bachelor +bacon +badge +bag +balance +balcony +ball +bamboo +banana +banner +bar +barely +bargain +barrel +base +basic +basket +battle +beach +bean +beauty +because +become +beef +before +begin +behave +behind +believe +below +belt +bench +benefit +best +betray +better +between +beyond +bicycle +bid +bike +bind +biology +bird +birth +bitter +black +blade +blame +blanket +blast +bleak +bless +blind +blood +blossom +blouse +blue +blur +blush +board +boat +body +boil +bomb +bone +bonus +book +boost +border +boring +borrow +boss +bottom +bounce +box +boy +bracket +brain +brand +brass +brave +bread +breeze +brick +bridge +brief +bright +bring +brisk +broccoli +broken +bronze +broom +brother +brown +brush +bubble +buddy +budget +buffalo +build +bulb +bulk +bullet +bundle +bunker +burden +burger +burst +bus +business +busy +butter +buyer +buzz +cabbage +cabin +cable +cactus +cage +cake +call +calm +camera +camp +can +canal +cancel +candy +cannon +canoe +canvas +canyon +capable +capital +captain +car +carbon +card +cargo +carpet +carry +cart +case +cash +casino +castle +casual +cat +catalog +catch +category +cattle +caught +cause +caution +cave +ceiling +celery +cement +census +century +cereal +certain +chair +chalk +champion +change +chaos +chapter +charge +chase +chat +cheap +check +cheese +chef +cherry +chest +chicken +chief +child +chimney +choice +choose +chronic +chuckle +chunk +churn +cigar +cinnamon +circle +citizen +city +civil +claim +clap +clarify +claw +clay +clean +clerk +clever +click +client +cliff +climb +clinic +clip +clock +clog +close +cloth +cloud +clown +club +clump +cluster +clutch +coach +coast +coconut +code +coffee +coil +coin +collect +color +column +combine +come +comfort +comic +common +company +concert +conduct +confirm +congress +connect +consider +control +convince +cook +cool +copper +copy +coral +core +corn +correct +cost +cotton +couch +country +couple +course +cousin +cover +coyote +crack +cradle +craft +cram +crane +crash +crater +crawl +crazy +cream +credit +creek +crew +cricket +crime +crisp +critic +crop +cross +crouch +crowd +crucial +cruel +cruise +crumble +crunch +crush +cry +crystal +cube +culture +cup +cupboard +curious +current +curtain +curve +cushion +custom +cute +cycle +dad +damage +damp +dance +danger +daring +dash +daughter +dawn +day +deal +debate +debris +decade +december +decide +decline +decorate +decrease +deer +defense +define +defy +degree +delay +deliver +demand +demise +denial +dentist +deny +depart +depend +deposit +depth +deputy +derive +describe +desert +design +desk +despair +destroy +detail +detect +develop +device +devote +diagram +dial +diamond +diary +dice +diesel +diet +differ +digital +dignity +dilemma +dinner +dinosaur +direct +dirt +disagree +discover +disease +dish +dismiss +disorder +display +distance +divert +divide +divorce +dizzy +doctor +document +dog +doll +dolphin +domain +donate +donkey +donor +door +dose +double +dove +draft +dragon +drama +drastic +draw +dream +dress +drift +drill +drink +drip +drive +drop +drum +dry +duck +dumb +dune +during +dust +dutch +duty +dwarf +dynamic +eager +eagle +early +earn +earth +easily +east +easy +echo +ecology +economy +edge +edit +educate +effort +egg +eight +either +elbow +elder +electric +elegant +element +elephant +elevator +elite +else +embark +embody +embrace +emerge +emotion +employ +empower +empty +enable +enact +end +endless +endorse +enemy +energy +enforce +engage +engine +enhance +enjoy +enlist +enough +enrich +enroll +ensure +enter +entire +entry +envelope +episode +equal +equip +era +erase +erode +erosion +error +erupt +escape +essay +essence +estate +eternal +ethics +evidence +evil +evoke +evolve +exact +example +excess +exchange +excite +exclude +excuse +execute +exercise +exhaust +exhibit +exile +exist +exit +exotic +expand +expect +expire +explain +expose +express +extend +extra +eye +eyebrow +fabric +face +faculty +fade +faint +faith +fall +false +fame +family +famous +fan +fancy +fantasy +farm +fashion +fat +fatal +father +fatigue +fault +favorite +feature +february +federal +fee +feed +feel +female +fence +festival +fetch +fever +few +fiber +fiction +field +figure +file +film +filter +final +find +fine +finger +finish +fire +firm +first +fiscal +fish +fit +fitness +fix +flag +flame +flash +flat +flavor +flee +flight +flip +float +flock +floor +flower +fluid +flush +fly +foam +focus +fog +foil +fold +follow +food +foot +force +forest +forget +fork +fortune +forum +forward +fossil +foster +found +fox +fragile +frame +frequent +fresh +friend +fringe +frog +front +frost +frown +frozen +fruit +fuel +fun +funny +furnace +fury +future +gadget +gain +galaxy +gallery +game +gap +garage +garbage +garden +garlic +garment +gas +gasp +gate +gather +gauge +gaze +general +genius +genre +gentle +genuine +gesture +ghost +giant +gift +giggle +ginger +giraffe +girl +give +glad +glance +glare +glass +glide +glimpse +globe +gloom +glory +glove +glow +glue +goat +goddess +gold +good +goose +gorilla +gospel +gossip +govern +gown +grab +grace +grain +grant +grape +grass +gravity +great +green +grid +grief +grit +grocery +group +grow +grunt +guard +guess +guide +guilt +guitar +gun +gym +habit +hair +half +hammer +hamster +hand +happy +harbor +hard +harsh +harvest +hat +have +hawk +hazard +head +health +heart +heavy +hedgehog +height +hello +helmet +help +hen +hero +hidden +high +hill +hint +hip +hire +history +hobby +hockey +hold +hole +holiday +hollow +home +honey +hood +hope +horn +horror +horse +hospital +host +hotel +hour +hover +hub +huge +human +humble +humor +hundred +hungry +hunt +hurdle +hurry +hurt +husband +hybrid +ice +icon +idea +identify +idle +ignore +ill +illegal +illness +image +imitate +immense +immune +impact +impose +improve +impulse +inch +include +income +increase +index +indicate +indoor +industry +infant +inflict +inform +inhale +inherit +initial +inject +injury +inmate +inner +innocent +input +inquiry +insane +insect +inside +inspire +install +intact +interest +into +invest +invite +involve +iron +island +isolate +issue +item +ivory +jacket +jaguar +jar +jazz +jealous +jeans +jelly +jewel +job +join +joke +journey +joy +judge +juice +jump +jungle +junior +junk +just +kangaroo +keen +keep +ketchup +key +kick +kid +kidney +kind +kingdom +kiss +kit +kitchen +kite +kitten +kiwi +knee +knife +knock +know +lab +label +labor +ladder +lady +lake +lamp +language +laptop +large +later +latin +laugh +laundry +lava +law +lawn +lawsuit +layer +lazy +leader +leaf +learn +leave +lecture +left +leg +legal +legend +leisure +lemon +lend +length +lens +leopard +lesson +letter +level +liar +liberty +library +license +life +lift +light +like +limb +limit +link +lion +liquid +list +little +live +lizard +load +loan +lobster +local +lock +logic +lonely +long +loop +lottery +loud +lounge +love +loyal +lucky +luggage +lumber +lunar +lunch +luxury +lyrics +machine +mad +magic +magnet +maid +mail +main +major +make +mammal +man +manage +mandate +mango +mansion +manual +maple +marble +march +margin +marine +market +marriage +mask +mass +master +match +material +math +matrix +matter +maximum +maze +meadow +mean +measure +meat +mechanic +medal +media +melody +melt +member +memory +mention +menu +mercy +merge +merit +merry +mesh +message +metal +method +middle +midnight +milk +million +mimic +mind +minimum +minor +minute +miracle +mirror +misery +miss +mistake +mix +mixed +mixture +mobile +model +modify +mom +moment +monitor +monkey +monster +month +moon +moral +more +morning +mosquito +mother +motion +motor +mountain +mouse +move +movie +much +muffin +mule +multiply +muscle +museum +mushroom +music +must +mutual +myself +mystery +myth +naive +name +napkin +narrow +nasty +nation +nature +near +neck +need +negative +neglect +neither +nephew +nerve +nest +net +network +neutral +never +news +next +nice +night +noble +noise +nominee +noodle +normal +north +nose +notable +note +nothing +notice +novel +now +nuclear +number +nurse +nut +oak +obey +object +oblige +obscure +observe +obtain +obvious +occur +ocean +october +odor +off +offer +office +often +oil +okay +old +olive +olympic +omit +once +one +onion +online +only +open +opera +opinion +oppose +option +orange +orbit +orchard +order +ordinary +organ +orient +original +orphan +ostrich +other +outdoor +outer +output +outside +oval +oven +over +own +owner +oxygen +oyster +ozone +pact +paddle +page +pair +palace +palm +panda +panel +panic +panther +paper +parade +parent +park +parrot +party +pass +patch +path +patient +patrol +pattern +pause +pave +payment +peace +peanut +pear +peasant +pelican +pen +penalty +pencil +people +pepper +perfect +permit +person +pet +phone +photo +phrase +physical +piano +picnic +picture +piece +pig +pigeon +pill +pilot +pink +pioneer +pipe +pistol +pitch +pizza +place +planet +plastic +plate +play +please +pledge +pluck +plug +plunge +poem +poet +point +polar +pole +police +pond +pony +pool +popular +portion +position +possible +post +potato +pottery +poverty +powder +power +practice +praise +predict +prefer +prepare +present +pretty +prevent +price +pride +primary +print +priority +prison +private +prize +problem +process +produce +profit +program +project +promote +proof +property +prosper +protect +proud +provide +public +pudding +pull +pulp +pulse +pumpkin +punch +pupil +puppy +purchase +purity +purpose +purse +push +put +puzzle +pyramid +quality +quantum +quarter +question +quick +quit +quiz +quote +rabbit +raccoon +race +rack +radar +radio +rail +rain +raise +rally +ramp +ranch +random +range +rapid +rare +rate +rather +raven +raw +razor +ready +real +reason +rebel +rebuild +recall +receive +recipe +record +recycle +reduce +reflect +reform +refuse +region +regret +regular +reject +relax +release +relief +rely +remain +remember +remind +remove +render +renew +rent +reopen +repair +repeat +replace +report +require +rescue +resemble +resist +resource +response +result +retire +retreat +return +reunion +reveal +review +reward +rhythm +rib +ribbon +rice +rich +ride +ridge +rifle +right +rigid +ring +riot +ripple +risk +ritual +rival +river +road +roast +robot +robust +rocket +romance +roof +rookie +room +rose +rotate +rough +round +route +royal +rubber +rude +rug +rule +run +runway +rural +sad +saddle +sadness +safe +sail +salad +salmon +salon +salt +salute +same +sample +sand +satisfy +satoshi +sauce +sausage +save +say +scale +scan +scare +scatter +scene +scheme +school +science +scissors +scorpion +scout +scrap +screen +script +scrub +sea +search +season +seat +second +secret +section +security +seed +seek +segment +select +sell +seminar +senior +sense +sentence +series +service +session +settle +setup +seven +shadow +shaft +shallow +share +shed +shell +sheriff +shield +shift +shine +ship +shiver +shock +shoe +shoot +shop +short +shoulder +shove +shrimp +shrug +shuffle +shy +sibling +sick +side +siege +sight +sign +silent +silk +silly +silver +similar +simple +since +sing +siren +sister +situate +six +size +skate +sketch +ski +skill +skin +skirt +skull +slab +slam +sleep +slender +slice +slide +slight +slim +slogan +slot +slow +slush +small +smart +smile +smoke +smooth +snack +snake +snap +sniff +snow +soap +soccer +social +sock +soda +soft +solar +soldier +solid +solution +solve +someone +song +soon +sorry +sort +soul +sound +soup +source +south +space +spare +spatial +spawn +speak +special +speed +spell +spend +sphere +spice +spider +spike +spin +spirit +split +spoil +sponsor +spoon +sport +spot +spray +spread +spring +spy +square +squeeze +squirrel +stable +stadium +staff +stage +stairs +stamp +stand +start +state +stay +steak +steel +stem +step +stereo +stick +still +sting +stock +stomach +stone +stool +story +stove +strategy +street +strike +strong +struggle +student +stuff +stumble +style +subject +submit +subway +success +such +sudden +suffer +sugar +suggest +suit +summer +sun +sunny +sunset +super +supply +supreme +sure +surface +surge +surprise +surround +survey +suspect +sustain +swallow +swamp +swap +swarm +swear +sweet +swift +swim +swing +switch +sword +symbol +symptom +syrup +system +table +tackle +tag +tail +talent +talk +tank +tape +target +task +taste +tattoo +taxi +teach +team +tell +ten +tenant +tennis +tent +term +test +text +thank +that +theme +then +theory +there +they +thing +this +thought +three +thrive +throw +thumb +thunder +ticket +tide +tiger +tilt +timber +time +tiny +tip +tired +tissue +title +toast +tobacco +today +toddler +toe +together +toilet +token +tomato +tomorrow +tone +tongue +tonight +tool +tooth +top +topic +topple +torch +tornado +tortoise +toss +total +tourist +toward +tower +town +toy +track +trade +traffic +tragic +train +transfer +trap +trash +travel +tray +treat +tree +trend +trial +tribe +trick +trigger +trim +trip +trophy +trouble +truck +true +truly +trumpet +trust +truth +try +tube +tuition +tumble +tuna +tunnel +turkey +turn +turtle +twelve +twenty +twice +twin +twist +two +type +typical +ugly +umbrella +unable +unaware +uncle +uncover +under +undo +unfair +unfold +unhappy +uniform +unique +unit +universe +unknown +unlock +until +unusual +unveil +update +upgrade +uphold +upon +upper +upset +urban +urge +usage +use +used +useful +useless +usual +utility +vacant +vacuum +vague +valid +valley +valve +van +vanish +vapor +various +vast +vault +vehicle +velvet +vendor +venture +venue +verb +verify +version +very +vessel +veteran +viable +vibrant +vicious +victory +video +view +village +vintage +violin +virtual +virus +visa +visit +visual +vital +vivid +vocal +voice +void +volcano +volume +vote +voyage +wage +wagon +wait +walk +wall +walnut +want +warfare +warm +warrior +wash +wasp +waste +water +wave +way +wealth +weapon +wear +weasel +weather +web +wedding +weekend +weird +welcome +west +wet +whale +what +wheat +wheel +when +where +whip +whisper +wide +width +wife +wild +will +win +window +wine +wing +wink +winner +winter +wire +wisdom +wise +wish +witness +wolf +woman +wonder +wood +wool +word +work +world +worry +worth +wrap +wreck +wrestle +wrist +write +wrong +yard +year +yellow +you +young +youth +zebra +zero +zone +zoo diff --git a/backend/src/config/mnemonic.words_ulf.txt b/backend/src/config/mnemonic.words_ulf.txt new file mode 100644 index 000000000..3b44fbd12 --- /dev/null +++ b/backend/src/config/mnemonic.words_ulf.txt @@ -0,0 +1,2048 @@ +Monumental +Volksbank +Beeren +huschen +leer +Haft +saagut +Positiv +daran +solide +dauerhaft +zahlungsfähig +beinhalten +weglassen +Ausmaß +irrtümlich +Impuls +darüber +Abriss +setzten +Herkunft +manipulierbar +anfängt +anliegen +Mutter +Beobachter +Zeichner +dran +genug +Medikament +Tanten +behindern +Johannes +Rand +Illusion +anzuwenden +Fehler +erniedrigen +gehören +Güte +unangenehm +Horst +Koordination +weltweit +geprägt +unerlässlich +einig +mitbringen +Dieb +dann +Karriere +Ethik +dich +Ursachen +beglücken +Wahl +dermaßen +spritzen +erbittert +Maler +täglich +Wohlstand +hübsch +Klarheit +voneinander +berühmt +Iris +plausibel +verlagern +Lauf +Foyer +Idol +spreizen +Hölderlin +Grenze +Code +Dogma +langfristig +Urzustand +verursacht +Fasching +Finger +König +barbarisch +einbringen +Disziplin +angreifen +speichern +Urheberrecht +ermorden +Diana +Auswirkung +beginnen +kooperativ +Ahnung +allen +bisschen +durften +Prostitution +Strahlen +Umschwung +Foto +taten +Mechanismus +Urvertrauen +Chef +feminin +nirgendwo +Absatzmarkt +welches +Entwicklung +gearbeitet +erblühen +umtauschen +Aufklärung +online +produktiv +Pest +Coach +Anblick +ursprünglich +schon +solange +eventuell +Tatsache +erforderlich +Buch +derartig +werden +auseinander +halten +Maurer +Himmel +Loch +Forum +Kluft +aufbauen +bricht +permanent +saugen +exponential +Fetzen +Mord +unausweichlich +untrennbar +skeptisch +geschützt +Gebäude +Butter +bezeichnet +Daunen +Journalist +ehrgeizig +System +Zugriff +Anwalt +Krone +ankommt +zulassen +Stufenplan +Raum +Sanktion +Währung +Tradition +Money +dafür +Gruppe +solch +geben +geholfen +frei +Rahmen +Rasen +feindlich +Wirklichkeit +Unheil +luden +Ausgleich +leugnen +erklärt +Vater +Ingenieur +Erfahrung +Stil +dörren +wozu +befassen +gemäß +Apotheke +Vegan +simultan +wehen +gang +immateriell +Wilhelm +fertig +kennen +korrigieren +Jahr +Industrie +hier +Glück +Anton +Bionik +abwaschen +Hannes +Diamant +Anweisung +angleichen +Fördern +Helene +glasklar +Abgaben +beflügeln +Trennung +Ziegler +überhaupt +Guido +rotieren +treiben +sowie +Begründung +Erdöl +selig +jegliche +belastbar +ehrlich +Eier +Schulden +Brutto +Paar +Sitz +hast +annähern +Neigung +Menü +messbar +vervollständigt +Erkenntnis +pendeln +Edwin +römisch +entstehen +Gefahr +Resonanz +ungleich +Sprache +Tsunami +Bindung +Sympathie +Bomber +Schlusswort +bislang +befreien +fegen +drastisch +greift +obwohl +bewährt +Jörg +drehen +Quartett +Betätigung +Szene +Kinder +Respekt +Empathie +eher +unwichtig +besser +nein +Kredit +liegen +zulegen +Forschung +Hurrikan +wesentlich +Deutschland +eintauchen +entzünden +betteln +Islam +Rohre +Müll +Tage +sinken +Hunger +fungieren +Radio +Lohn +lenken +Container +marode +gering +Ozean +Revolution +Meter +tausend +Kalkulation +blau +Hautfarbe +Kurt +Ding +Mathematiker +jene +renovieren +Popstar +auferlegen +unübersichtlich +fantasievoll +Bedürfnisse +Maßstab +Feier +Onkel +essen +Stein +einzeln +Woche +Sekunde +Phantasie +Blockade +Chip +Moment +lüften +Jasmin +aufrecht +eisern +oder +Fachsprache +Komponist +Vermögen +allmählich +Urwissen +selbstregulierend +Brust +Leute +Gegner +Pause +unqualifiziert +August +Umdrehung +wegdenken +gucken +leihen +vordringen +Durst +Seite +fast +hinaus +Binnenland +Bund +sollt +Albert +Smartphone +Kriminalität +Protest +Fremdkosten +klingen +Chicago +Baum +sammeln +sehen +soviel +Horoskop +keiner +Pension +soweit +Quantensprung +intrinsisch +anno +Züge +Zeug +Wissenschaft +dass +loszulassen +brauchen +Lehrer +rufen +Lama +Sparen +größte +Kerl +enthalten +Flügel +Rabatt +ehrt +endlich +religiös +Orchester +braten +Feedback +exemplarisch +Zitat +Recht +toll +Zusammenfassung +hervor +Eigentum +teuer +nichtkommerziell +benachbart +leider +Fahrzeug +glauben +putzen +geübt +begünstigen +Kasten +zuspitzen +meckern +organisation +loben +Anthropologie +Seminar +moralisch +Last +merken +Samen +kassieren +Bube +Engpass +Hopfen +Hirte +Gefängnis +Gedanke +bepacken +brillant +verrichtet +drohen +Katze +reif +Fossilien +gezeigt +Packen +persönlich +denen +wegweisend +Horror +Diplomat +Japan +pflanzlich +kaltblütig +Kunde +Geruch +Patriarch +Garnele +bedingungslos +Prinzip +Vergänglichkeit +stört +hinein +Tomate +halb +geplatzt +Theologe +Vogel +September +Steak +repräsentieren +heißen +hoch +hinblick +Wunsch +frustriert +Fidel +Blödsinn +früh +Birne +Hülle +loslegen +jetzt +Biene +regnen +Celsius +hören +genommen +Fleisch +diejenigen +davon +vorrangig +sonst +herrschend +ertragen +Neuorientierung +nächsten +sozusagen +Sabbat +honorieren +verwirklichen +Mobbing +Annahme +Hügel +Bedeutung +Risiko +riskieren +ermöglichen +hemmen +Frist +Klima +böse +sofern +Paul +vertieft +missionieren +zuvor +Nagel +backen +getauft +dazu +Blech +zufolge +Koch +immerwährend +Regenwald +Finnland +altruistisch +grau +Oktober +Universität +Philosoph +Ungarn +Wirtschaft +hinlänglich +Abteil +sperrt +aggressiv +Gast +externe +Saat +Zustand +losfliegen +egal +Dubai +aktiv +flattern +zunehmend +Bauweise +erreichen +Markus +gegründet +zwölf +Rente +zwar +leicht +Fischer +Emotion +dunkel +Vision +fressen +dritter +athletisch +warum +Lage +bestimmt +Mitwirkender +Totenkopf +Qualität +hegen +Ecke +erhalten +fuhr +Sklave +getätigt +belügen +gutmachen +breit +konnten +Obst +subventionieren +Pflicht +Planet +keimen +sogar +deshalb +Milch +Gesicht +zögern +fundamental +Zwang +typisch +gefunden +offen +Publikum +wieso +strukturell +Voraussetzung +umhin +Geduld +dient +Professor +wechseln +Minute +Ärmel +Konto +waren +Information +ganz +studieren +Reihenhaus +Henry +oftmals +Apfelbaum +reißen +Labor +effektiv +Umfeld +sogenannten +Insolvenz +erzwingen +später +funktionieren +Meile +extrem +Hallo +mitdenken +Heim +Praxis +lediglich +Kohle +inmitten +berichten +Soja +Firma +rasant +relativ +doof +Belgien +Rendite +Auge +abschreiben +Direktor +unsere +Absätze +plus +suchen +inklusive +somit +Spirit +verändern +Test +Bewohner +eindeutig +Strom +leiten +Zentralbank +Austausch +pickt +weise +Tourismus +spielen +Absicht +Beachtung +Spekulation +ernst +telefonieren +Trotz +Technologie +indigene +gelöst +Thomas +Blüte +Ferienjob +geteilt +Heinrich +gelangen +Situation +Kunst +Zufall +Haufen +geworden +Wurzel +Punkt +Temperatur +zukunftsfähig +Opfer +Josef +nutzen +Kauf +annehmen +Klaus +berauben +Griff +erdacht +neulich +geändert +besitzen +liberal +kopieren +superreich +bekommen +Kolumbus +Mangel +Steffi +Hase +bahnbrechend +Norbert +Karte +kreativ +unverändert +effizient +Historiker +anschließend +Stichtag +These +nimmt +Finanzblase +wegnehmen +heutige +Hexe +Foliant +Flamme +Diktatur +klick +Mitleidenschaft +dick +vorliegend +verhindern +Klasse +uralt +Abfall +stoßen +lernen +ethnisch +Eleganz +schmackhaft +helfen +Wind +Pfarrer +neueste +anfangen +Erich +ausatmen +Präzision +Stück +aktuell +unproduktiv +dastehen +runter +Figaro +Internet +Gäste +sträflich +Angst +Bedarf +Ozonloch +Bioprodukte +mögen +Abraham +Sohn +Nebensitzer +zudem +Konzept +Russland +erzeugt +Stress +Hanau +Hugo +zehn +resultieren +Dach +junge +lehnen +Bewirtschaftung +gekommen +erproben +durch +Häuser +gigantisch +unendlich +Wegfall +Irland +Reparatur +perfekt +Pilz +Zauberwort +Dorf +darin +absolut +Anbau +Dung +müssen +betreiben +sieht +investieren +Ansatz +Vorwort +ablegen +Verantwortung +gebaut +Dreck +Feld +explizit +Harmonie +Rangordnung +maximal +meiner +vereinigt +Hamburg +clever +global +unfreiwillig +tierisch +Bayern +Importgüter +schenken +Donnerstag +Puffer +Rohstoff +britisch +Samuel +Handel +anstatt +Sprung +Dollar +Lösung +Engagement +Oberst +unmöglich +Goethe +zehren +Humorist +neuartig +plötzlich +Graf +ging +intakt +tragen +nahm +zusätzlich +Potenzial +beeinflussen +ziemlich +Beitrag +Fest +Hektik +beliebt +ergibt +ausbeuten +vorhanden +klagt +wegrationalisieren +bequem +werben +Welle +Spuren +decken +autistisch +Satz +musizieren +Umlaufbahn +nützlich +simpel +sauber +Fortschritt +losgelöst +bist +weder +ungünstig +Meer +treffen +peinlich +einnehmen +bewegte +notbedingt +benennen +Zugvogel +identisch +Infrastruktur +Blase +erfinden +modern +gähnen +Sportler +alte +aufs +Kampf +Nikolaus +fröhlich +Stockwerk +Fabel +Brasilien +passend +abgeschaut +Pädagoge +militärisch +Spaß +beugen +Einwohner +Ressourcen +Lunge +Discounter +insbesondere +lukrativ +bloß +erarbeiten +Referat +Neuseeland +Rose +Abhängigkeit +Gänse +Duft +Pilot +vernachlässigt +Lausbub +Darsteller +Bezahlung +Wörtchen +Seele +altbekannt +Seil +Lothar +irgendwann +Ironie +Titel +zumindest +Aussage +bezwingen +Errungenschaft +Medaille +Uhren +unmittelbar +treten +richtung +wahr +mitverursachen +bilden +Tennisspielerin +jenseits +Mädchen +aber +Territorium +Fenchel +Spende +Definition +draußen +parallel +annimmt +allgemein +King +verbessert +sowohl +Methode +Affe +Dank +Versorgung +Staunen +Vorteil +gegangen +ansonsten +kommt +beim +Gefrierpunkt +senkt +Elster +unter +Äther +niemand +dennoch +Zeit +Schriftsteller +klettern +boshaft +ohne +riesig +sorgfältig +Slums +Beschränkung +Gehalt +hergestellt +Urlaub +Gabe +Kapazität +werfen +suggerieren +Rolle +Guthaben +Höhle +nehmen +unfair +gemacht +Flur +kannst +Rassenkonflikte +Herbizide +Twitter +iPhone +Bausparkasse +entfalten +Vorbild +Orientale +erwidern +abrupt +mich +dein +Krieg +umkämpft +Kriterium +behaupten +Mitarbeiter +runden +Wort +hereinholen +beurteilen +Frieden +totalversagen +Africa +konfrontiert +Grün +sofort +ersten +Dotter +Facebook +gelingen +Unsinn +Arthur +umstellen +Kultur +Urmutter +Pyramide +Obsoleszenz +Biedermeier +gewehrt +heraus +ideal +ihnen +ausnahmslos +gerecht +satt +Inspiration +Sägemehl +jemanden +pflegen +Laden +optimieren +spazieren +mitnehmen +sondern +Nektar +anbringen +vorne +günstig +Vorfall +blind +widerstehen +einpendeln +einmal +Krebs +Einleitung +Institut +desto +Alibi +Besen +auftreten +zuschauen +Haar +Baukasten +ließen +polar +Umsetzung +Millionär +prima +gilt +insgesamt +Wartung +inländisch +reiten +befinden +bekannt +Niveau +Faktor +Antike +gutschreiben +antreiben +Drama +Floh +praktisch +unzählig +heikel +leiblich +Augsburg +Keller +Abendessen +anheben +retten +schnell +erhält +voriges +Wertschätzung +unnütz +neunziger +Prozess +Flutwelle +umfangreich +Geld +haben +gekauft +Öse +zukommen +Querdenker +genmanipuliert +müde +Seerose +gewaltfrei +Fiat +Negativität +faul +Datum +erfunden +gepachtet +sauer +bisher +wollen +Bonität +erbringen +restlich +oben +Fuß +Flotte +Robert +Phase +Inflation +tapfer +weinen +zeigen +hoffentlich +hingen +mutig +prüfen +lustig +gravierend +Fondue +ehemalig +mitharbeiten +Steuern +Holland +stabil +dessen +Initiative +geblieben +nachfolgen +Befehl +Nordstern +dahinter +Gott +Erbsen +Unmenschlichkeit +Reise +euch +Papa +Ersatz +Bande +womit +gerne +auskommen +nahezu +Brücke +Küche +Traum +selten +manche +häkeln +Summe +würdigen +einräumen +Lebzeiten +bitte +atmen +Licht +gekriegt +Neidisch +umso +Erde +Wolfgang +letzten +eignen +dezentral +genießen +klein +Sanft +pathologisch +anbieten +zugänglich +Flug +Bonus +regulieren +stolz +Zyklus +zerstören +fiel +Basis +delegieren +Legehenne +Leser +Fieber +wunderbar +Familie +Hippie +Gemeinschaft +Stunde +Zwergstaat +sagen +fokussieren +toxisch +psychologisch +fragen +Bach +zaudern +Lektorat +Ausland +Fackel +mehr +Datenbank +runzlig +erwähnen +Zimmerleute +Spuk +Preis +Einführung +gewidmet +talentiert +Gregor +Inhalt +Human +Südafrika +Sozialabgaben +Erfüllung +benutzt +Englisch +Nationalstaat +Krankheit +gönnen +unschätzbar +Fähigkeit +Tellerwäscher +damit +bebauen +Ehre +Software +stirbt +Honig +Altlasten +zuwider +Hobby +murmeln +beziffern +degradieren +geformt +Zufriedenheit +erlaubt +Fluss +Ratgeber +Fernseher +Hesse +jammern +verzeihen +Wagen +Mahlzeit +Abwicklung +Lizenz +Umwelt +Papst +Wolke +Fontane +Weggefährte +Fläche +ausdrücklich +stetig +dumm +Webseite +besonders +signifikant +exakt +virtuell +weichen +hilft +Topmanager +dazwischen +dringend +herzlich +kaum +Haupt +gespielt +einher +Arzt +gewöhnt +florieren +Anziehung +senden +Fichte +eingeführt +Anlass +Locke +geboren +zuerst +mahnen +evolutionär +beißen +Forelle +wenden +Umsatz +drucken +führen +Pflock +Haiti +Miesmacher +Estland +Staatseinkommen +Motte +dort +aufhören +Konsum +gutwillig +Befürworter +Ketzer +Blick +Hühner +bunkern +erinnern +Fohlen +hatten +zwitschern +Gentechnik +Berlin +foppen +Gier +Leonardo +väterlich +Hähnchen +bereits +Designer +rebellieren +Ufer +auch +Hütte +&Übel +Eden +Hermann +ungewöhnlich +Partei +gnädig +womöglich +Winter +anzetteln +vorprogrammiert +Fips +Flagge +zinslos +weil +bewahrt +Werk +Atom +Akademie +Anker +Sonne +derselbe +Sockel +Somalia +wann +erzählen +Abstand +enorm +indem +etwas +Erasmus +vorkommen +Rede +Tokio +dreifach +halfen +Zivilisation +Luftfahrt +Endverbraucher +Mama +Angebot +Vorschlag +hart +lokal +Sorte +Priorität +jedoch +genügend +dadurch +Branche +großartig +Regal +garantiert +unbewusst +Migrant +Auerhahn +David +stärken +Erbe +notfalls +hindurch +wickeln +quasi +darf +comedy +gehen +Start +verdeckt +Dosis +Brezel +Element +Kurs +Ämter +leuchten +zwischen +Beileid +weiblich +Ruder +Zoologe +aushalten +neugeboren +spüren +Ingwer +fließen +Idee +Samstag +trainieren +Flandern +Auffassung +ziehen +Masse +Nina +Arten +Gnade +Spezial +unkonventionell +Wald +Jugend +Busch +Fabian +dokumentieren +Felix +Film +belohnt +Gertrud +architektur +derzeitig +echt +Tagtraum +Margret +Objektivität +Sieger +empfinden +Beamten +akzeptieren +laut +Sternenstaub +Stadt +Aristoteles +Ferrari +finden +Google +Westen +Fratze +Bauer +Kreislauf +wovon +Jürgen +gerade +Platz +Madonna +Zahnersatz +Marianne +euer +Privat +Schatten +hundert +besucht +aufwärts +dynamisch +Sahne +viel +Teufel +Gebrauchsanweisung +Gradido +sieben +Flucht +holen +baden +ändern +jüngeren +Natur +chinesisch +Rohmaterial +Hauch +Konkurrenz +fiktiv +akkumulieren +Ball +beenden +bemüht +recyclebar +gedruckt +vegetarisch +woran +erwerben +lasst +bleiben +Radfahrer +Bücher +Klavier +genannt +Quelle +erheblich +gegenseitig +abzahlen +stagnieren +Hubert +Ende +Crash +Trinkwasser +Franz +Insekt +sensibilisieren +Erneuerung +Sehnen +Maus +Frau +betonung +stiege +Porsche +beide +absurd +dato +Österreich +beteiligen +dies +gezwungen +anvertrauen +Tilgung +Feder +logisch +konventionell +fatal +kulinarisch +Abholzung +Cicero +nostalgischen +schützen +brachte +Metzger +geehrt +Flasche +bringt +Villa +Krise +bietet +Entlastung +ausführung +Wikipedia +stellen +Park +Video +Papiergeld +voll +inzwischen +Jäger +Topf +ülzen +umgekehrt +Hanf +Februar +zirkulieren +John +heben +Novellierung +unfähig +servieren +Meier +jeweilig +Heuschrecke +daher +Alexander +Peter +erkannt +Gehirn +lateinisch +anpassbar +anderen +Artikel +Wucht +Leben +sein +exzellent +beantworten +Asche +reduzieren +Hersteller +Victor +zumal +Plage +hassen +fünf +liebevoll +für +Acker +morphogenetisch +Sachverhalt +umpolen +gibt +Busfahrer +beherzigen +weitergeben +brav +jeder +sich +Galaxis +steht +Maschine +erzielen +Sanierung +Kraft +Netto +Begabung +ersetzen +mindest +gestorben +Osten +Gebiet +Zweifel +zugleich +wild +kameradschaftlich +Farbe +Mitmensch +bevölkern +gesamt +Mittel +Reporter +Kilometer +kostenlos +mobil +wehren +herunter +Ansehen +erfrischend +Hotel +Analyse +Griechisch +Abwurf +käuflich +Bernd +entgegengesetzt +Bewusstsein +ankaufen +zurzeit +Impressum +Toast +Ladung +Verfütterung +Form +Wasser +gesund +noch +horchen +Variante +Anleitung +Pazifik +Wiederherstellung +Wandel +transformieren +Tisch +verknappt +Material +Realisierung +einer +Daimler +unvorstellbar +meldete +Strickmuster +stammen +Menge +Verifizieren +tief +Puzzle +Gepflogenheit +Ziel +dürfen +doch +Sinn +Region +fangen +zuteil +Anspruch +kehrte +Freund +Fimmel +darum +Girokonto +Zweck +Wohngemeinschaft +Projekt +schweigen +Kupfer +tauchen +holzig +Tendenz +abhalten +Nummer +bald +Töne +Salvador +Kapitel +Ibiza +Komfort +wobei +lachen +Wagnis +metaphorisch +gelb +bevor +unnatürlich +Leasing +bemerkenswert +zugute +beruhen +soeben +Kopf +wischen +appellieren +gelten +statt +Futter +Erdball +benötigt +futsch +Symbol +wofür +Glanz +beispiellos +normalen +mitfinanzieren +Frucht +italienisch +woher +allzu +beleben +weigern +Senf +Gift +atemlos +Cäsar +Begegnung +horten +sobald +Luxus +biologisch +Wettbewerb +Umkehrschluss +fallen +Darlehen +klug +anpreisen +doppelt +abwechslungsreich +Werner +nannte +Wittenberg +existenzbedrohend +deren +zynisch +Feuer +Leistung +Ideologie +Enkel +diskutiert +pervers +Brot +Ordnung +blubbern +einander +College +folgen +Anreiz +Agrarfläche +aufdecken +zerrinnen +ergründen +spalten +unehelich +Experte +viertel +gezogen +Mitspieler +geklappt +Kette +Petrus +Nahrung +Georg +Patent +Unkenntlich +Waage +ernähren +Botschafter +hell +Zelle +Silbe +pfiffig +Mystisch +Acht +ahnen +erkämpft +Team +zunächst +Benzin +falsch +erwarten +raffen +Auflage +Thema +ernten +Monat +lindern +meisten +zurückerlangen +Fenster +unabhängig +Jesus +geistig +divers +Göttingen +unruhig +Kategorie +fassen +hinzu +Wachstum +Sven +Chemie +quälen +Herde +standen +jährlich +Anhang +nötig +Hirsch +derjenige +Kurzgeschichte +ökologische +Theater +willkommen +ausüben +Kanal +nennt +Name +wussten +drücken +aufnehmen +Äste +Rücken +intuition +hätte +Zunahme +Gläubiger +abzählen +Phänomen +Ablage +spontan +spannend +Vanessa +Asien +gewusst +elektronisch +derb +getilgt +Antwort +geeignet +Bote +gequält +Anerkennung +Bilanz +natürlich +machbar +Verpackung +Blut +Eltern +Himbeere +rumfliegen +Senioren +zwingen +Spitze +Taschendiebe +steckt +Monster +Egotrip +Helmut +Bibel +geerbt +zitieren +Ameisenbau +Rekordgewinne +Hände +ergänzen +danach +orden +hinter +wenn +paddeln +gutes +Hinsicht +wegen +Teilhabe +Gesellschaft +christlich +Bezugsquelle +Igor +ausprobieren +Endpreis +links +gekürzt +einkaufen +Lied +Gerhard +gelohnt +nackt +Geburt +gelehrt +einseitig +gedeckt +hinweg +Eduard +Premiere +demografisch +ihre +höchste +wichtigsten +Aufmerksamkeit +Horde +physisch +Arbeitsklima +Brief +Notdurft +proportional +fordern +Ewig +denken +Daniel +Arabisch +edle +golden +Minimum +pure +beibringen +Boden +Anzahl +erschaffen +Energie +sehr +Gerücht +Generation +Räuber +Motivation +Chance +dabei +Programm +segensreich +April +ignorieren +Nase +epochal +Boot +faszinieren +Heilkunde +Helikopter +Computer +Kabarettist +wenig +zukünftig +sechzehn +stimmt +getragen +reagieren +Esoterik +Koralle +Dame +Katastrophe +liefern +Grund +Elend +ausreichen +Notenbank +Garten +zutiefst +Immobilien +Aspekt +naiv +besprechen +zählen +Terminologie +Amerika +Atmosphäre +Iran +debatte +Sound +Zugang +fair +unrentabel +baut +kollektiv +schief +Bank +Mann +Apropos +Ergebnis +Niederlande +Mietshaus +errichten +Ereignis +Portal +erhielten +erleben +Haus +Dschungel +Null +Pleite +Seegras +Entdeckung +also +Ebene +Anbeginn +kohärent +Autor +Mensch +hielt +Reich +Land +bekloppt +außerdem +Berg +gleich +sind +Argument +einverstanden +Euro +Sektor +dagegen +Knappheit +Armut +innerhalb +Blume +Problem +Bruder +Netzwerk +Orte +bedrängen +Aufgabe diff --git a/backend/src/config/mnemonic.words_ulf_org.txt b/backend/src/config/mnemonic.words_ulf_org.txt new file mode 100644 index 000000000..d0f96c49c --- /dev/null +++ b/backend/src/config/mnemonic.words_ulf_org.txt @@ -0,0 +1,2048 @@ +Monumental +Volksbank +Beeren +huschen +leer +Haft +saagut +Positiv +daran +solide +dauerhaft +zahlungsfähig +beinhalten +weglassen +Ausmaß +irrtümlich +Impuls +darüber +Abriss +setzten +Herkunft +manipulierbar +anfängt +anliegen +Mutter +Beobachter +Zeichner +dran +genug +Medikament +Tanten +behindern +Johannes +Rand +Illusion +anzuwenden +Fehler +erniedrigen +gehören +Güte +unangenehm +Horst +Koordination +weltweit +geprägt +unerlässlich +einig +mitbringen +Dieb +dann +Karriere +Ethik +dich +Ursachen +beglücken +Wahl +dermaßen +spritzen +erbittert +Maler +täglich +Wohlstand +hübsch +Klarheit +voneinander +berühmt +Iris +plausibel +verlagern +Lauf +Foyer +Idol +spreizen +Hölderlin +Grenze +Code +Dogma +langfristig +Urzustand +verursacht +Fasching +Finger +König +barbarisch +einbringen +Disziplin +angreifen +speichern +Urheberrecht +ermorden +Diana +Auswirkung +beginnen +kooperativ +Ahnung +allen +bisschen +durften +Prostitution +Strahlen +Umschwung +Foto +taten +Mechanismus +Urvertrauen +Chef +feminin +nirgendwo +Absatzmarkt +welches +Entwicklung +gearbeitet +erblühen +umtauschen +Aufklärung +online +produktiv +Pest +Coach +Anblick +ursprünglich +schon +solange +eventuell +Tatsache +erforderlich +Buch +derartig +werden +auseinander +halten +Maurer +Himmel +Loch +Forum +Kluft +aufbauen +bricht +permanent +saugen +exponential +Fetzen +Mord +unausweichlich +untrennbar +skeptisch +geschützt +Gebäude +Butter +bezeichnet +Daunen +Journalist +ehrgeizig +System +Zugriff +Anwalt +Krone +ankommt +zulassen +Stufenplan +Raum +Sanktion +Währung +Tradition +Money +dafür +Gruppe +solch +geben +geholfen +frei +Rahmen +Rasen +feindlich +Wirklichkeit +Unheil +luden +Ausgleich +leugnen +erklärt +Vater +Ingenieur +Erfahrung +Stil +dörren +wozu +befassen +gemäß +Apotheke +Vegan +simultan +wehen +gang +immateriell +Wilhelm +fertig +kennen +korrigieren +Jahr +Industrie +hier +Glück +Anton +Bionik +abwaschen +Hannes +Diamant +Anweisung +angleichen +Fördern +Helene +glasklar +Abgaben +beflügeln +Trennung +Ziegler +überhaupt +Guido +rotieren +treiben +sowie +Begründung +Erdöl +selig +jegliche +belastbar +ehrlich +Eier +Schulden +Brutto +Paar +Sitz +hast +annähern +Neigung +Menü +messbar +vervollständigt +Erkenntnis +pendeln +Edwin +römisch +entstehen +Gefahr +Resonanz +ungleich +Sprache +Tsunami +Bindung +Sympathie +Bomber +Schlusswort +bislang +befreien +fegen +drastisch +greift +obwohl +bewährt +Jörg +drehen +Quartett +Betätigung +Szene +Kinder +Respekt +Empathie +eher +unwichtig +besser +nein +Kredit +liegen +zulegen +Forschung +Hurrikan +wesentlich +Deutschland +eintauchen +entzünden +betteln +Islam +Rohre +Müll +Tage +sinken +Hunger +fungieren +Radio +Lohn +lenken +Container +marode +gering +Ozean +Revolution +Meter +tausend +Kalkulation +blau +Hautfarbe +Kurt +Ding +Mathematiker +jene +renovieren +Popstar +auferlegen +unübersichtlich +fantasievoll +Bedürfnisse +Maßstab +Feier +Onkel +essen +Stein +einzeln +Woche +Sekunde +Phantasie +Blockade +Chip +Moment +lüften +Jasmin +aufrecht +eisern +oder +Fachsprache +Komponist +Vermögen +allmählich +Urwissen +selbstregulierend +Brust +Leute +Gegner +Pause +unqualifiziert +August +Umdrehung +wegdenken +gucken +leihen +vordringen +Durst +Seite +fast +hinaus +Binnenland +Bund +sollt +Albert +Smartphone +Kriminalität +Protest +Fremdkosten +klingen +Chicago +Baum +sammeln +sehen +soviel +Horoskop +keiner +Pension +soweit +Quantensprung +intrinsisch +anno +Züge +Zeug +Wissenschaft +dass +loszulassen +brauchen +Lehrer +rufen +Lama +Sparen +größte +Kerl +enthalten +Flügel +Rabatt +ehrt +endlich +religiös +Orchester +braten +Feedback +exemplarisch +Zitat +Recht +toll +Zusammenfassung +hervor +Eigentum +teuer +nichtkommerziell +benachbart +leider +Fahrzeug +glauben +putzen +geübt +begünstigen +Kasten +zuspitzen +meckern +organisation +loben +Anthropologie +Seminar +moralisch +Last +merken +Samen +kassieren +Bube +Engpass +Hopfen +Hirte +Gefängnis +Gedanke +bepacken +brillant +verrichtet +drohen +Katze +reif +Fossilien +gezeigt +Packen +persönlich +denen +wegweisend +Horror +Diplomat +Japan +pflanzlich +kaltblütig +Kunde +Geruch +Patriarch +Garnele +bedingungslos +Prinzip +Vergänglichkeit +stört +hinein +Tomate +halb +geplatzt +Theologe +Vogel +September +Steak +repräsentieren +heißen +hoch +hinblick +Wunsch +frustriert +Fidel +Blödsinn +früh +Birne +Hülle +loslegen +jetzt +Biene +regnen +Celsius +hören +genommen +Fleisch +diejenigen +davon +vorrangig +sonst +herrschend +ertragen +Neuorientierung +nächsten +sozusagen +Sabbat +honorieren +verwirklichen +Mobbing +Annahme +Hügel +Bedeutung +Risiko +riskieren +ermöglichen +hemmen +Frist +Klima +böse +sofern +Paul +vertieft +missionieren +zuvor +Nagel +backen +getauft +dazu +Blech +zufolge +Koch +immerwährend +Regenwald +Finnland +altruistisch +grau +Oktober +Universität +Philosoph +Ungarn +Wirtschaft +hinlänglich +Abteil +sperrt +aggressiv +Gast +externe +Saat +Zustand +losfliegen +egal +Dubai +aktiv +flattern +zunehmend +Bauweise +erreichen +Markus +gegründet +zwölf +Rente +zwar +leicht +Fischer +Emotion +dunkel +Vision +fressen +dritter +athletisch +warum +Lage +bestimmt +Mitwirkender +Totenkopf +Qualität +hegen +Ecke +erhalten +fuhr +Sklave +getätigt +belügen +gutmachen +breit +konnten +Obst +subventionieren +Pflicht +Planet +keimen +sogar +deshalb +Milch +Gesicht +zögern +fundamental +Zwang +typisch +gefunden +offen +Publikum +wieso +strukturell +Voraussetzung +umhin +Geduld +dient +Professor +wechseln +Minute +Ärmel +Konto +waren +Information +ganz +studieren +Reihenhaus +Henry +oftmals +Apfelbaum +reißen +Labor +effektiv +Umfeld +sogenannten +Insolvenz +erzwingen +später +funktionieren +Meile +extrem +Hallo +mitdenken +Heim +Praxis +lediglich +Kohle +inmitten +berichten +Soja +Firma +rasant +relativ +doof +Belgien +Rendite +Auge +abschreiben +Direktor +unsere +Absätze +plus +suchen +inklusive +somit +Spirit +verändern +Test +Bewohner +eindeutig +Strom +leiten +Zentralbank +Austausch +pickt +weise +Tourismus +spielen +Absicht +Beachtung +Spekulation +ernst +telefonieren +Trotz +Technologie +indigene +gelöst +Thomas +Blüte +Ferienjob +geteilt +Heinrich +gelangen +Situation +Kunst +Zufall +Haufen +geworden +Wurzel +Punkt +Temperatur +zukunftsfähig +Opfer +Josef +nutzen +Kauf +annehmen +Klaus +berauben +Griff +erdacht +neulich +geändert +besitzen +liberal +kopieren +superreich +bekommen +Kolumbus +Mangel +Steffi +Hase +bahnbrechend +Norbert +Karte +kreativ +unverändert +effizient +Historiker +anschließend +Stichtag +These +nimmt +Finanzblase +wegnehmen +heutige +Hexe +Foliant +Flamme +Diktatur +klick +Mitleidenschaft +dick +vorliegend +verhindern +Klasse +uralt +Abfall +stoßen +lernen +ethnisch +Eleganz +schmackhaft +helfen +Wind +Pfarrer +neueste +anfangen +Erich +ausatmen +Präzision +Stück +aktuell +unproduktiv +dastehen +runter +Figaro +Internet +Gäste +sträflich +Angst +Bedarf +Ozonloch +Bioprodukte +mögen +Abraham +Sohn +Nebensitzer +zudem +Konzept +Russland +erzeugt +Stress +Hanau +Hugo +zehn +resultieren +Dach +junge +lehnen +Bewirtschaftung +gekommen +erproben +durch +Häuser +gigantisch +unendlich +Wegfall +Irland +Reparatur +perfekt +Pilz +Zauberwort +Dorf +darin +absolut +Anbau +Dung +müssen +betreiben +sieht +investieren +Ansatz +Vorwort +ablegen +Verantwortung +gebaut +Dreck +Feld +explizit +Harmonie +Rangordnung +maximal +meiner +vereinigt +Hamburg +clever +global +unfreiwillig +tierisch +Bayern +Importgüter +schenken +Donnerstag +Puffer +Rohstoff +britisch +Samuel +Handel +anstatt +Sprung +Dollar +Lösung +Engagement +Oberst +unmöglich +Goethe +zehren +Humorist +neuartig +plötzlich +Graf +ging +intakt +tragen +nahm +zusätzlich +Potenzial +beeinflussen +ziemlich +Beitrag +Fest +Hektik +beliebt +ergibt +ausbeuten +vorhanden +klagt +wegrationalisieren +bequem +werben +Welle +Spuren +decken +autistisch +Satz +musizieren +Umlaufbahn +nützlich +simpel +sauber +Fortschritt +losgelöst +bist +weder +ungünstig +Meer +treffen +peinlich +einnehmen +bewegte +notbedingt +benennen +Zugvogel +identisch +Infrastruktur +Blase +erfinden +modern +gähnen +Sportler +alte +aufs +Kampf +Nikolaus +fröhlich +Stockwerk +Fabel +Brasilien +passend +abgeschaut +Pädagoge +militärisch +Spaß +beugen +Einwohner +Ressourcen +Lunge +Discounter +insbesondere +lukrativ +bloß +erarbeiten +Referat +Neuseeland +Rose +Abhängigkeit +Gänse +Duft +Pilot +vernachlässigt +Lausbub +Darsteller +Bezahlung +Wörtchen +Seele +altbekannt +Seil +Lothar +irgendwann +Ironie +Titel +zumindest +Aussage +bezwingen +Errungenschaft +Medaille +Uhren +unmittelbar +treten +richtung +wahr +mitverursachen +bilden +Tennisspielerin +jenseits +Mädchen +aber +Territorium +Fenchel +Spende +Definition +draußen +parallel +annimmt +allgemein +King +verbessert +sowohl +Methode +Affe +Dank +Versorgung +Staunen +Vorteil +gegangen +ansonsten +kommt +beim +Gefrierpunkt +senkt +Elster +unter +Äther +niemand +dennoch +Zeit +Schriftsteller +klettern +boshaft +ohne +riesig +sorgfältig +Slums +Beschränkung +Gehalt +hergestellt +Urlaub +Gabe +Kapazität +werfen +suggerieren +Rolle +Guthaben +Höhle +nehmen +unfair +gemacht +Flur +kannst +Rassenkonflikte +Herbizide +Twitter +iPhone +Bausparkasse +entfalten +Vorbild +Orientale +erwidern +abrupt +mich +dein +Krieg +umkämpft +Kriterium +behaupten +Mitarbeiter +runden +Wort +hereinholen +beurteilen +Frieden +totalversagen +Africa +konfrontiert +Grün +sofort +ersten +Dotter +Facebook +gelingen +Unsinn +Arthur +umstellen +Kultur +Urmutter +Pyramide +Obsoleszenz +Biedermeier +gewehrt +heraus +ideal +ihnen +ausnahmslos +gerecht +satt +Inspiration +Sägemehl +jemanden +pflegen +Laden +optimieren +spazieren +mitnehmen +sondern +Nektar +anbringen +vorne +günstig +Vorfall +blind +widerstehen +einpendeln +einmal +Krebs +Einleitung +Institut +desto +Alibi +Besen +auftreten +zuschauen +Haar +Baukasten +ließen +polar +Umsetzung +Millionär +prima +gilt +insgesamt +Wartung +inländisch +reiten +befinden +bekannt +Niveau +Faktor +Antike +gutschreiben +antreiben +Drama +Floh +praktisch +unzählig +heikel +leiblich +Augsburg +Keller +Abendessen +anheben +retten +schnell +erhält +voriges +Wertschätzung +unnütz +neunziger +Prozess +Flutwelle +umfangreich +Geld +haben +gekauft +Öse +zukommen +Querdenker +genmanipuliert +müde +Seerose +gewaltfrei +Fiat +Negativität +faul +Datum +erfunden +gepachtet +sauer +bisher +wollen +Bonität +erbringen +restlich +oben +Fuß +Flotte +Robert +Phase +Inflation +tapfer +weinen +zeigen +hoffentlich +hingen +mutig +prüfen +lustig +gravierend +Fondue +ehemalig +mitharbeiten +Steuern +Holland +stabil +dessen +Initiative +geblieben +nachfolgen +Befehl +Nordstern +dahinter +Gott +Erbsen +Unmenschlichkeit +Reise +euch +Papa +Ersatz +Bande +womit +gerne +auskommen +nahezu +Brücke +Küche +Traum +selten +manche +häkeln +Summe +würdigen +einräumen +Lebzeiten +bitte +atmen +Licht +gekriegt +Neidisch +umso +Erde +Wolfgang +letzten +eignen +dezentral +genießen +klein +Sanft +pathologisch +anbieten +zugänglich +Flug +Bonus +regulieren +stolz +Zyklus +zerstören +fiel +Basis +delegieren +Legehenne +Leser +Fieber +wunderbar +Familie +Hippie +Gemeinschaft +Stunde +Zwergstaat +sagen +fokussieren +toxisch +psychologisch +fragen +Bach +zaudern +Lektorat +Ausland +Fackel +mehr +Datenbank +runzlig +erwähnen +Zimmerleute +Spuk +Preis +Einführung +gewidmet +talentiert +Gregor +Inhalt +Human +Südafrika +Sozialabgaben +Erfüllung +benutzt +Englisch +Nationalstaat +Krankheit +gönnen +unschätzbar +Fähigkeit +Tellerwäscher +damit +bebauen +Ehre +Software +stirbt +Honig +Altlasten +zuwider +Hobby +murmeln +beziffern +degradieren +geformt +Zufriedenheit +erlaubt +Fluss +Ratgeber +Fernseher +Hesse +jammern +verzeihen +Wagen +Mahlzeit +Abwicklung +Lizenz +Umwelt +Papst +Wolke +Fontane +Weggefährte +Fläche +ausdrücklich +stetig +dumm +Webseite +besonders +signifikant +exakt +virtuell +weichen +hilft +Topmanager +dazwischen +dringend +herzlich +kaum +Haupt +gespielt +einher +Arzt +gewöhnt +florieren +Anziehung +senden +Fichte +eingeführt +Anlass +Locke +geboren +zuerst +mahnen +evolutionär +beißen +Forelle +wenden +Umsatz +drucken +führen +Pflock +Haiti +Miesmacher +Estland +Staatseinkommen +Motte +dort +aufhören +Konsum +gutwillig +Befürworter +Ketzer +Blick +Hühner +bunkern +erinnern +Fohlen +hatten +zwitschern +Gentechnik +Berlin +foppen +Gier +Leonardo +väterlich +Hähnchen +bereits +Designer +rebellieren +Ufer +auch +Hütte +Übel +Eden +Hermann +ungewöhnlich +Partei +gnädig +womöglich +Winter +anzetteln +vorprogrammiert +Fips +Flagge +zinslos +weil +bewahrt +Werk +Atom +Akademie +Anker +Sonne +derselbe +Sockel +Somalia +wann +erzählen +Abstand +enorm +indem +etwas +Erasmus +vorkommen +Rede +Tokio +dreifach +halfen +Zivilisation +Luftfahrt +Endverbraucher +Mama +Angebot +Vorschlag +hart +lokal +Sorte +Priorität +jedoch +genügend +dadurch +Branche +großartig +Regal +garantiert +unbewusst +Migrant +Auerhahn +David +stärken +Erbe +notfalls +hindurch +wickeln +quasi +darf +comedy +gehen +Start +verdeckt +Dosis +Brezel +Element +Kurs +Ämter +leuchten +zwischen +Beileid +weiblich +Ruder +Zoologe +aushalten +neugeboren +spüren +Ingwer +fließen +Idee +Samstag +trainieren +Flandern +Auffassung +ziehen +Masse +Nina +Arten +Gnade +Spezial +unkonventionell +Wald +Jugend +Busch +Fabian +dokumentieren +Felix +Film +belohnt +Gertrud +architektur +derzeitig +echt +Tagtraum +Margret +Objektivität +Sieger +empfinden +Beamten +akzeptieren +laut +Sternenstaub +Stadt +Aristoteles +Ferrari +finden +Google +Westen +Fratze +Bauer +Kreislauf +wovon +Jürgen +gerade +Platz +Madonna +Zahnersatz +Marianne +euer +Privat +Schatten +hundert +besucht +aufwärts +dynamisch +Sahne +viel +Teufel +Gebrauchsanweisung +Gradido +sieben +Flucht +holen +baden +ändern +jüngeren +Natur +chinesisch +Rohmaterial +Hauch +Konkurrenz +fiktiv +akkumulieren +Ball +beenden +bemüht +recyclebar +gedruckt +vegetarisch +woran +erwerben +lasst +bleiben +Radfahrer +Bücher +Klavier +genannt +Quelle +erheblich +gegenseitig +abzahlen +stagnieren +Hubert +Ende +Crash +Trinkwasser +Franz +Insekt +sensibilisieren +Erneuerung +Sehnen +Maus +Frau +betonung +stiege +Porsche +beide +absurd +dato +Österreich +beteiligen +dies +gezwungen +anvertrauen +Tilgung +Feder +logisch +konventionell +fatal +kulinarisch +Abholzung +Cicero +nostalgischen +schützen +brachte +Metzger +geehrt +Flasche +bringt +Villa +Krise +bietet +Entlastung +ausführung +Wikipedia +stellen +Park +Video +Papiergeld +voll +inzwischen +Jäger +Topf +ülzen +umgekehrt +Hanf +Februar +zirkulieren +John +heben +Novellierung +unfähig +servieren +Meier +jeweilig +Heuschrecke +daher +Alexander +Peter +erkannt +Gehirn +lateinisch +anpassbar +anderen +Artikel +Wucht +Leben +sein +exzellent +beantworten +Asche +reduzieren +Hersteller +Victor +zumal +Plage +hassen +fünf +liebevoll +für +Acker +morphogenetisch +Sachverhalt +umpolen +gibt +Busfahrer +beherzigen +weitergeben +brav +jeder +sich +Galaxis +steht +Maschine +erzielen +Sanierung +Kraft +Netto +Begabung +ersetzen +mindest +gestorben +Osten +Gebiet +Zweifel +zugleich +wild +kameradschaftlich +Farbe +Mitmensch +bevölkern +gesamt +Mittel +Reporter +Kilometer +kostenlos +mobil +wehren +herunter +Ansehen +erfrischend +Hotel +Analyse +Griechisch +Abwurf +käuflich +Bernd +entgegengesetzt +Bewusstsein +ankaufen +zurzeit +Impressum +Toast +Ladung +Verfütterung +Form +Wasser +gesund +noch +horchen +Variante +Anleitung +Pazifik +Wiederherstellung +Wandel +transformieren +Tisch +verknappt +Material +Realisierung +einer +Daimler +unvorstellbar +meldete +Strickmuster +stammen +Menge +Verifizieren +tief +Puzzle +Gepflogenheit +Ziel +dürfen +doch +Sinn +Region +fangen +zuteil +Anspruch +kehrte +Freund +Fimmel +darum +Girokonto +Zweck +Wohngemeinschaft +Projekt +schweigen +Kupfer +tauchen +holzig +Tendenz +abhalten +Nummer +bald +Töne +Salvador +Kapitel +Ibiza +Komfort +wobei +lachen +Wagnis +metaphorisch +gelb +bevor +unnatürlich +Leasing +bemerkenswert +zugute +beruhen +soeben +Kopf +wischen +appellieren +gelten +statt +Futter +Erdball +benötigt +futsch +Symbol +wofür +Glanz +beispiellos +normalen +mitfinanzieren +Frucht +italienisch +woher +allzu +beleben +weigern +Senf +Gift +atemlos +Cäsar +Begegnung +horten +sobald +Luxus +biologisch +Wettbewerb +Umkehrschluss +fallen +Darlehen +klug +anpreisen +doppelt +abwechslungsreich +Werner +nannte +Wittenberg +existenzbedrohend +deren +zynisch +Feuer +Leistung +Ideologie +Enkel +diskutiert +pervers +Brot +Ordnung +blubbern +einander +College +folgen +Anreiz +Agrarfläche +aufdecken +zerrinnen +ergründen +spalten +unehelich +Experte +viertel +gezogen +Mitspieler +geklappt +Kette +Petrus +Nahrung +Georg +Patent +Unkenntlich +Waage +ernähren +Botschafter +hell +Zelle +Silbe +pfiffig +Mystisch +Acht +ahnen +erkämpft +Team +zunächst +Benzin +falsch +erwarten +raffen +Auflage +Thema +ernten +Monat +lindern +meisten +zurückerlangen +Fenster +unabhängig +Jesus +geistig +divers +Göttingen +unruhig +Kategorie +fassen +hinzu +Wachstum +Sven +Chemie +quälen +Herde +standen +jährlich +Anhang +nötig +Hirsch +derjenige +Kurzgeschichte +ökologische +Theater +willkommen +ausüben +Kanal +nennt +Name +wussten +drücken +aufnehmen +Äste +Rücken +intuition +hätte +Zunahme +Gläubiger +abzählen +Phänomen +Ablage +spontan +spannend +Vanessa +Asien +gewusst +elektronisch +derb +getilgt +Antwort +geeignet +Bote +gequält +Anerkennung +Bilanz +natürlich +machbar +Verpackung +Blut +Eltern +Himbeere +rumfliegen +Senioren +zwingen +Spitze +Taschendiebe +steckt +Monster +Egotrip +Helmut +Bibel +geerbt +zitieren +Ameisenbau +Rekordgewinne +Hände +ergänzen +danach +orden +hinter +wenn +paddeln +gutes +Hinsicht +wegen +Teilhabe +Gesellschaft +christlich +Bezugsquelle +Igor +ausprobieren +Endpreis +links +gekürzt +einkaufen +Lied +Gerhard +gelohnt +nackt +Geburt +gelehrt +einseitig +gedeckt +hinweg +Eduard +Premiere +demografisch +ihre +höchste +wichtigsten +Aufmerksamkeit +Horde +physisch +Arbeitsklima +Brief +Notdurft +proportional +fordern +Ewig +denken +Daniel +Arabisch +edle +golden +Minimum +pure +beibringen +Boden +Anzahl +erschaffen +Energie +sehr +Gerücht +Generation +Räuber +Motivation +Chance +dabei +Programm +segensreich +April +ignorieren +Nase +epochal +Boot +faszinieren +Heilkunde +Helikopter +Computer +Kabarettist +wenig +zukünftig +sechzehn +stimmt +getragen +reagieren +Esoterik +Koralle +Dame +Katastrophe +liefern +Grund +Elend +ausreichen +Notenbank +Garten +zutiefst +Immobilien +Aspekt +naiv +besprechen +zählen +Terminologie +Amerika +Atmosphäre +Iran +debatte +Sound +Zugang +fair +unrentabel +baut +kollektiv +schief +Bank +Mann +Apropos +Ergebnis +Niederlande +Mietshaus +errichten +Ereignis +Portal +erhielten +erleben +Haus +Dschungel +Null +Pleite +Seegras +Entdeckung +also +Ebene +Anbeginn +kohärent +Autor +Mensch +hielt +Reich +Land +bekloppt +außerdem +Berg +gleich +sind +Argument +einverstanden +Euro +Sektor +dagegen +Knappheit +Armut +innerhalb +Blume +Problem +Bruder +Netzwerk +Orte +bedrängen +Aufgabe From d642bff68324b836e206edef3dc18f080d83c8a4 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 1 Nov 2021 00:08:53 +0100 Subject: [PATCH 07/47] optimization: save private key always --- backend/src/graphql/resolver/UserResolver.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 8089fc677..8ca10b748 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -120,11 +120,7 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { return [pubKey, privKey] } -const generateKeys = async ( - email: string, - savePrivkey: boolean, - savePassphrase: boolean, -): Promise => { +const generateKeys = async (email: string, savePassphrase: boolean): Promise => { const mNewUser = await LoginUser.findOneOrFail({ email }) const lang = mNewUser.language /* @@ -150,10 +146,7 @@ const generateKeys = async ( const gradidoKeyPair = KeyPairEd25519Create(passphrase) mNewUser.pubKey = gradidoKeyPair[0] - - if (savePrivkey) { - mNewUser.privKey = gradidoKeyPair[1] - } + mNewUser.privKey = gradidoKeyPair[1] await mNewUser.save().catch(() => { throw new Error(`Error saving new generated pub/priv keys, email: ${email}`) @@ -307,7 +300,7 @@ export class UserResolver { throw new Error('insert user failed') }) - const keys = await generateKeys(email, true, true) + const keys = await generateKeys(email, true) const pubkey = keys[0] // TODO: we do not login the user as before, since session management is not yet ported From c2ffc9b5f48f4365df60d2e5ad8ec3514488da52 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 1 Nov 2021 00:10:02 +0100 Subject: [PATCH 08/47] todo --- backend/src/graphql/resolver/UserResolver.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 8ca10b748..e49bc1f9a 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -122,6 +122,7 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { const generateKeys = async (email: string, savePassphrase: boolean): Promise => { const mNewUser = await LoginUser.findOneOrFail({ email }) + // TODO figure mnemonic database const lang = mNewUser.language /* if (LANG_DE == lang) { From c4df8184565827404649279762bc82a0e52f037f Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 1 Nov 2021 00:10:39 +0100 Subject: [PATCH 09/47] optimization: dont assign unused variable --- backend/src/graphql/resolver/UserResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index e49bc1f9a..a5b4c9968 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -123,7 +123,7 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { const generateKeys = async (email: string, savePassphrase: boolean): Promise => { const mNewUser = await LoginUser.findOneOrFail({ email }) // TODO figure mnemonic database - const lang = mNewUser.language + // const lang = mNewUser.language /* if (LANG_DE == lang) { mnemonic_type = ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES; From d4dd8e5e21522c149d59f14c6fb32cc715c5a773 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 1 Nov 2021 00:12:09 +0100 Subject: [PATCH 10/47] optimization: always save passphrase --- backend/src/graphql/resolver/UserResolver.ts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a5b4c9968..53c18f076 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -120,7 +120,7 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { return [pubKey, privKey] } -const generateKeys = async (email: string, savePassphrase: boolean): Promise => { +const generateKeys = async (email: string): Promise => { const mNewUser = await LoginUser.findOneOrFail({ email }) // TODO figure mnemonic database // const lang = mNewUser.language @@ -132,16 +132,14 @@ const generateKeys = async (email: string, savePassphrase: boolean): Promise { - throw new Error('insert user backup failed') - }) - } + await loginUserBackup.save().catch(() => { + throw new Error('insert user backup failed') + }) // keys const gradidoKeyPair = KeyPairEd25519Create(passphrase) @@ -301,7 +299,7 @@ export class UserResolver { throw new Error('insert user failed') }) - const keys = await generateKeys(email, true) + const keys = await generateKeys(email) const pubkey = keys[0] // TODO: we do not login the user as before, since session management is not yet ported From 2a764eef3b508dd8f31447841a32d8181c42bc04 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 1 Nov 2021 00:16:40 +0100 Subject: [PATCH 11/47] optimization: additional check for passphrase to actually have enought words, various other stuff --- backend/src/graphql/resolver/UserResolver.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 53c18f076..65945d668 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -83,8 +83,8 @@ const PassphraseGenerate = (): string[] => { } const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { - if (!passphrase.length) { - throw new Error('passphrase empty') + if (!passphrase.length || passphrase.length < PHRASE_WORD_COUNT) { + throw new Error('passphrase empty or to short') } const wordIndicies = [] @@ -96,18 +96,15 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { // if (!wordIndicies || (!wordIndicies[0] && !wordIndicies[1] && !wordIndicies[2] && !wordIndicies[3])) { // return null; // } - const clearPassphrase = passphrase.join(' ') - // Assuming this calls `crypto_hash_sha512_init` const hash = crypto_hash_sha512_instance() - // **** convert word indices into uint64 **** // To prevent breaking existing passphrase-hash combinations word indices will be put into 64 Bit Variable to mimic first implementation of algorithms for (let i = 0; i < PHRASE_WORD_COUNT; i++) { const value = BigInt(wordIndicies[i]) hash.update(Buffer.from(bigintToBuf(value))) } - // **** end converting into uint64 ***** + const clearPassphrase = passphrase.join(' ') hash.update(Buffer.from(clearPassphrase)) const outputHashBuffer = Buffer.alloc(crypto_hash_sha512_BYTES) hash.final(outputHashBuffer) From 22bdcae05b15de3fc327dc12e7c41c166c5b9cf3 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 1 Nov 2021 00:54:12 +0100 Subject: [PATCH 12/47] proper encoding for the German special characters (was windows encoding, now is utf8) --- .../config/mnemonic.words_ulf.encoding.txt | 2048 +++++++++++++++++ 1 file changed, 2048 insertions(+) create mode 100644 backend/src/config/mnemonic.words_ulf.encoding.txt diff --git a/backend/src/config/mnemonic.words_ulf.encoding.txt b/backend/src/config/mnemonic.words_ulf.encoding.txt new file mode 100644 index 000000000..1be83cc2e --- /dev/null +++ b/backend/src/config/mnemonic.words_ulf.encoding.txt @@ -0,0 +1,2048 @@ +Monumental +Volksbank +Beeren +huschen +leer +Haft +saagut +Positiv +daran +solide +dauerhaft +zahlungsfähig +beinhalten +weglassen +Ausmaß +irrtümlich +Impuls +darüber +Abriss +setzten +Herkunft +manipulierbar +anfängt +anliegen +Mutter +Beobachter +Zeichner +dran +genug +Medikament +Tanten +behindern +Johannes +Rand +Illusion +anzuwenden +Fehler +erniedrigen +gehören +Güte +unangenehm +Horst +Koordination +weltweit +geprägt +unerlässlich +einig +mitbringen +Dieb +dann +Karriere +Ethik +dich +Ursachen +beglücken +Wahl +dermaßen +spritzen +erbittert +Maler +täglich +Wohlstand +hübsch +Klarheit +voneinander +berühmt +Iris +plausibel +verlagern +Lauf +Foyer +Idol +spreizen +Hölderlin +Grenze +Code +Dogma +langfristig +Urzustand +verursacht +Fasching +Finger +König +barbarisch +einbringen +Disziplin +angreifen +speichern +Urheberrecht +ermorden +Diana +Auswirkung +beginnen +kooperativ +Ahnung +allen +bisschen +durften +Prostitution +Strahlen +Umschwung +Foto +taten +Mechanismus +Urvertrauen +Chef +feminin +nirgendwo +Absatzmarkt +welches +Entwicklung +gearbeitet +erblühen +umtauschen +Aufklärung +online +produktiv +Pest +Coach +Anblick +ursprünglich +schon +solange +eventuell +Tatsache +erforderlich +Buch +derartig +werden +auseinander +halten +Maurer +Himmel +Loch +Forum +Kluft +aufbauen +bricht +permanent +saugen +exponential +Fetzen +Mord +unausweichlich +untrennbar +skeptisch +geschützt +Gebäude +Butter +bezeichnet +Daunen +Journalist +ehrgeizig +System +Zugriff +Anwalt +Krone +ankommt +zulassen +Stufenplan +Raum +Sanktion +Währung +Tradition +Money +dafür +Gruppe +solch +geben +geholfen +frei +Rahmen +Rasen +feindlich +Wirklichkeit +Unheil +luden +Ausgleich +leugnen +erklärt +Vater +Ingenieur +Erfahrung +Stil +dörren +wozu +befassen +gemäß +Apotheke +Vegan +simultan +wehen +gang +immateriell +Wilhelm +fertig +kennen +korrigieren +Jahr +Industrie +hier +Glück +Anton +Bionik +abwaschen +Hannes +Diamant +Anweisung +angleichen +Fördern +Helene +glasklar +Abgaben +beflügeln +Trennung +Ziegler +überhaupt +Guido +rotieren +treiben +sowie +Begründung +Erdöl +selig +jegliche +belastbar +ehrlich +Eier +Schulden +Brutto +Paar +Sitz +hast +annähern +Neigung +Menü +messbar +vervollständigt +Erkenntnis +pendeln +Edwin +römisch +entstehen +Gefahr +Resonanz +ungleich +Sprache +Tsunami +Bindung +Sympathie +Bomber +Schlusswort +bislang +befreien +fegen +drastisch +greift +obwohl +bewährt +Jörg +drehen +Quartett +Betätigung +Szene +Kinder +Respekt +Empathie +eher +unwichtig +besser +nein +Kredit +liegen +zulegen +Forschung +Hurrikan +wesentlich +Deutschland +eintauchen +entzünden +betteln +Islam +Rohre +Müll +Tage +sinken +Hunger +fungieren +Radio +Lohn +lenken +Container +marode +gering +Ozean +Revolution +Meter +tausend +Kalkulation +blau +Hautfarbe +Kurt +Ding +Mathematiker +jene +renovieren +Popstar +auferlegen +unübersichtlich +fantasievoll +Bedürfnisse +Maßstab +Feier +Onkel +essen +Stein +einzeln +Woche +Sekunde +Phantasie +Blockade +Chip +Moment +lüften +Jasmin +aufrecht +eisern +oder +Fachsprache +Komponist +Vermögen +allmählich +Urwissen +selbstregulierend +Brust +Leute +Gegner +Pause +unqualifiziert +August +Umdrehung +wegdenken +gucken +leihen +vordringen +Durst +Seite +fast +hinaus +Binnenland +Bund +sollt +Albert +Smartphone +Kriminalität +Protest +Fremdkosten +klingen +Chicago +Baum +sammeln +sehen +soviel +Horoskop +keiner +Pension +soweit +Quantensprung +intrinsisch +anno +Züge +Zeug +Wissenschaft +dass +loszulassen +brauchen +Lehrer +rufen +Lama +Sparen +größte +Kerl +enthalten +Flügel +Rabatt +ehrt +endlich +religiös +Orchester +braten +Feedback +exemplarisch +Zitat +Recht +toll +Zusammenfassung +hervor +Eigentum +teuer +nichtkommerziell +benachbart +leider +Fahrzeug +glauben +putzen +geübt +begünstigen +Kasten +zuspitzen +meckern +organisation +loben +Anthropologie +Seminar +moralisch +Last +merken +Samen +kassieren +Bube +Engpass +Hopfen +Hirte +Gefängnis +Gedanke +bepacken +brillant +verrichtet +drohen +Katze +reif +Fossilien +gezeigt +Packen +persönlich +denen +wegweisend +Horror +Diplomat +Japan +pflanzlich +kaltblütig +Kunde +Geruch +Patriarch +Garnele +bedingungslos +Prinzip +Vergänglichkeit +stört +hinein +Tomate +halb +geplatzt +Theologe +Vogel +September +Steak +repräsentieren +heißen +hoch +hinblick +Wunsch +frustriert +Fidel +Blödsinn +früh +Birne +Hülle +loslegen +jetzt +Biene +regnen +Celsius +hören +genommen +Fleisch +diejenigen +davon +vorrangig +sonst +herrschend +ertragen +Neuorientierung +nächsten +sozusagen +Sabbat +honorieren +verwirklichen +Mobbing +Annahme +Hügel +Bedeutung +Risiko +riskieren +ermöglichen +hemmen +Frist +Klima +böse +sofern +Paul +vertieft +missionieren +zuvor +Nagel +backen +getauft +dazu +Blech +zufolge +Koch +immerwährend +Regenwald +Finnland +altruistisch +grau +Oktober +Universität +Philosoph +Ungarn +Wirtschaft +hinlänglich +Abteil +sperrt +aggressiv +Gast +externe +Saat +Zustand +losfliegen +egal +Dubai +aktiv +flattern +zunehmend +Bauweise +erreichen +Markus +gegründet +zwölf +Rente +zwar +leicht +Fischer +Emotion +dunkel +Vision +fressen +dritter +athletisch +warum +Lage +bestimmt +Mitwirkender +Totenkopf +Qualität +hegen +Ecke +erhalten +fuhr +Sklave +getätigt +belügen +gutmachen +breit +konnten +Obst +subventionieren +Pflicht +Planet +keimen +sogar +deshalb +Milch +Gesicht +zögern +fundamental +Zwang +typisch +gefunden +offen +Publikum +wieso +strukturell +Voraussetzung +umhin +Geduld +dient +Professor +wechseln +Minute +Ärmel +Konto +waren +Information +ganz +studieren +Reihenhaus +Henry +oftmals +Apfelbaum +reißen +Labor +effektiv +Umfeld +sogenannten +Insolvenz +erzwingen +später +funktionieren +Meile +extrem +Hallo +mitdenken +Heim +Praxis +lediglich +Kohle +inmitten +berichten +Soja +Firma +rasant +relativ +doof +Belgien +Rendite +Auge +abschreiben +Direktor +unsere +Absätze +plus +suchen +inklusive +somit +Spirit +verändern +Test +Bewohner +eindeutig +Strom +leiten +Zentralbank +Austausch +pickt +weise +Tourismus +spielen +Absicht +Beachtung +Spekulation +ernst +telefonieren +Trotz +Technologie +indigene +gelöst +Thomas +Blüte +Ferienjob +geteilt +Heinrich +gelangen +Situation +Kunst +Zufall +Haufen +geworden +Wurzel +Punkt +Temperatur +zukunftsfähig +Opfer +Josef +nutzen +Kauf +annehmen +Klaus +berauben +Griff +erdacht +neulich +geändert +besitzen +liberal +kopieren +superreich +bekommen +Kolumbus +Mangel +Steffi +Hase +bahnbrechend +Norbert +Karte +kreativ +unverändert +effizient +Historiker +anschließend +Stichtag +These +nimmt +Finanzblase +wegnehmen +heutige +Hexe +Foliant +Flamme +Diktatur +klick +Mitleidenschaft +dick +vorliegend +verhindern +Klasse +uralt +Abfall +stoßen +lernen +ethnisch +Eleganz +schmackhaft +helfen +Wind +Pfarrer +neueste +anfangen +Erich +ausatmen +Präzision +Stück +aktuell +unproduktiv +dastehen +runter +Figaro +Internet +Gäste +sträflich +Angst +Bedarf +Ozonloch +Bioprodukte +mögen +Abraham +Sohn +Nebensitzer +zudem +Konzept +Russland +erzeugt +Stress +Hanau +Hugo +zehn +resultieren +Dach +junge +lehnen +Bewirtschaftung +gekommen +erproben +durch +Häuser +gigantisch +unendlich +Wegfall +Irland +Reparatur +perfekt +Pilz +Zauberwort +Dorf +darin +absolut +Anbau +Dung +müssen +betreiben +sieht +investieren +Ansatz +Vorwort +ablegen +Verantwortung +gebaut +Dreck +Feld +explizit +Harmonie +Rangordnung +maximal +meiner +vereinigt +Hamburg +clever +global +unfreiwillig +tierisch +Bayern +Importgüter +schenken +Donnerstag +Puffer +Rohstoff +britisch +Samuel +Handel +anstatt +Sprung +Dollar +Lösung +Engagement +Oberst +unmöglich +Goethe +zehren +Humorist +neuartig +plötzlich +Graf +ging +intakt +tragen +nahm +zusätzlich +Potenzial +beeinflussen +ziemlich +Beitrag +Fest +Hektik +beliebt +ergibt +ausbeuten +vorhanden +klagt +wegrationalisieren +bequem +werben +Welle +Spuren +decken +autistisch +Satz +musizieren +Umlaufbahn +nützlich +simpel +sauber +Fortschritt +losgelöst +bist +weder +ungünstig +Meer +treffen +peinlich +einnehmen +bewegte +notbedingt +benennen +Zugvogel +identisch +Infrastruktur +Blase +erfinden +modern +gähnen +Sportler +alte +aufs +Kampf +Nikolaus +fröhlich +Stockwerk +Fabel +Brasilien +passend +abgeschaut +Pädagoge +militärisch +Spaß +beugen +Einwohner +Ressourcen +Lunge +Discounter +insbesondere +lukrativ +bloß +erarbeiten +Referat +Neuseeland +Rose +Abhängigkeit +Gänse +Duft +Pilot +vernachlässigt +Lausbub +Darsteller +Bezahlung +Wörtchen +Seele +altbekannt +Seil +Lothar +irgendwann +Ironie +Titel +zumindest +Aussage +bezwingen +Errungenschaft +Medaille +Uhren +unmittelbar +treten +richtung +wahr +mitverursachen +bilden +Tennisspielerin +jenseits +Mädchen +aber +Territorium +Fenchel +Spende +Definition +draußen +parallel +annimmt +allgemein +King +verbessert +sowohl +Methode +Affe +Dank +Versorgung +Staunen +Vorteil +gegangen +ansonsten +kommt +beim +Gefrierpunkt +senkt +Elster +unter +Äther +niemand +dennoch +Zeit +Schriftsteller +klettern +boshaft +ohne +riesig +sorgfältig +Slums +Beschränkung +Gehalt +hergestellt +Urlaub +Gabe +Kapazität +werfen +suggerieren +Rolle +Guthaben +Höhle +nehmen +unfair +gemacht +Flur +kannst +Rassenkonflikte +Herbizide +Twitter +iPhone +Bausparkasse +entfalten +Vorbild +Orientale +erwidern +abrupt +mich +dein +Krieg +umkämpft +Kriterium +behaupten +Mitarbeiter +runden +Wort +hereinholen +beurteilen +Frieden +totalversagen +Africa +konfrontiert +Grün +sofort +ersten +Dotter +Facebook +gelingen +Unsinn +Arthur +umstellen +Kultur +Urmutter +Pyramide +Obsoleszenz +Biedermeier +gewehrt +heraus +ideal +ihnen +ausnahmslos +gerecht +satt +Inspiration +Sägemehl +jemanden +pflegen +Laden +optimieren +spazieren +mitnehmen +sondern +Nektar +anbringen +vorne +günstig +Vorfall +blind +widerstehen +einpendeln +einmal +Krebs +Einleitung +Institut +desto +Alibi +Besen +auftreten +zuschauen +Haar +Baukasten +ließen +polar +Umsetzung +Millionär +prima +gilt +insgesamt +Wartung +inländisch +reiten +befinden +bekannt +Niveau +Faktor +Antike +gutschreiben +antreiben +Drama +Floh +praktisch +unzählig +heikel +leiblich +Augsburg +Keller +Abendessen +anheben +retten +schnell +erhält +voriges +Wertschätzung +unnütz +neunziger +Prozess +Flutwelle +umfangreich +Geld +haben +gekauft +Öse +zukommen +Querdenker +genmanipuliert +müde +Seerose +gewaltfrei +Fiat +Negativität +faul +Datum +erfunden +gepachtet +sauer +bisher +wollen +Bonität +erbringen +restlich +oben +Fuß +Flotte +Robert +Phase +Inflation +tapfer +weinen +zeigen +hoffentlich +hingen +mutig +prüfen +lustig +gravierend +Fondue +ehemalig +mitharbeiten +Steuern +Holland +stabil +dessen +Initiative +geblieben +nachfolgen +Befehl +Nordstern +dahinter +Gott +Erbsen +Unmenschlichkeit +Reise +euch +Papa +Ersatz +Bande +womit +gerne +auskommen +nahezu +Brücke +Küche +Traum +selten +manche +häkeln +Summe +würdigen +einräumen +Lebzeiten +bitte +atmen +Licht +gekriegt +Neidisch +umso +Erde +Wolfgang +letzten +eignen +dezentral +genießen +klein +Sanft +pathologisch +anbieten +zugänglich +Flug +Bonus +regulieren +stolz +Zyklus +zerstören +fiel +Basis +delegieren +Legehenne +Leser +Fieber +wunderbar +Familie +Hippie +Gemeinschaft +Stunde +Zwergstaat +sagen +fokussieren +toxisch +psychologisch +fragen +Bach +zaudern +Lektorat +Ausland +Fackel +mehr +Datenbank +runzlig +erwähnen +Zimmerleute +Spuk +Preis +Einführung +gewidmet +talentiert +Gregor +Inhalt +Human +Südafrika +Sozialabgaben +Erfüllung +benutzt +Englisch +Nationalstaat +Krankheit +gönnen +unschätzbar +Fähigkeit +Tellerwäscher +damit +bebauen +Ehre +Software +stirbt +Honig +Altlasten +zuwider +Hobby +murmeln +beziffern +degradieren +geformt +Zufriedenheit +erlaubt +Fluss +Ratgeber +Fernseher +Hesse +jammern +verzeihen +Wagen +Mahlzeit +Abwicklung +Lizenz +Umwelt +Papst +Wolke +Fontane +Weggefährte +Fläche +ausdrücklich +stetig +dumm +Webseite +besonders +signifikant +exakt +virtuell +weichen +hilft +Topmanager +dazwischen +dringend +herzlich +kaum +Haupt +gespielt +einher +Arzt +gewöhnt +florieren +Anziehung +senden +Fichte +eingeführt +Anlass +Locke +geboren +zuerst +mahnen +evolutionär +beißen +Forelle +wenden +Umsatz +drucken +führen +Pflock +Haiti +Miesmacher +Estland +Staatseinkommen +Motte +dort +aufhören +Konsum +gutwillig +Befürworter +Ketzer +Blick +Hühner +bunkern +erinnern +Fohlen +hatten +zwitschern +Gentechnik +Berlin +foppen +Gier +Leonardo +väterlich +Hähnchen +bereits +Designer +rebellieren +Ufer +auch +Hütte +&Übel +Eden +Hermann +ungewöhnlich +Partei +gnädig +womöglich +Winter +anzetteln +vorprogrammiert +Fips +Flagge +zinslos +weil +bewahrt +Werk +Atom +Akademie +Anker +Sonne +derselbe +Sockel +Somalia +wann +erzählen +Abstand +enorm +indem +etwas +Erasmus +vorkommen +Rede +Tokio +dreifach +halfen +Zivilisation +Luftfahrt +Endverbraucher +Mama +Angebot +Vorschlag +hart +lokal +Sorte +Priorität +jedoch +genügend +dadurch +Branche +großartig +Regal +garantiert +unbewusst +Migrant +Auerhahn +David +stärken +Erbe +notfalls +hindurch +wickeln +quasi +darf +comedy +gehen +Start +verdeckt +Dosis +Brezel +Element +Kurs +Ämter +leuchten +zwischen +Beileid +weiblich +Ruder +Zoologe +aushalten +neugeboren +spüren +Ingwer +fließen +Idee +Samstag +trainieren +Flandern +Auffassung +ziehen +Masse +Nina +Arten +Gnade +Spezial +unkonventionell +Wald +Jugend +Busch +Fabian +dokumentieren +Felix +Film +belohnt +Gertrud +architektur +derzeitig +echt +Tagtraum +Margret +Objektivität +Sieger +empfinden +Beamten +akzeptieren +laut +Sternenstaub +Stadt +Aristoteles +Ferrari +finden +Google +Westen +Fratze +Bauer +Kreislauf +wovon +Jürgen +gerade +Platz +Madonna +Zahnersatz +Marianne +euer +Privat +Schatten +hundert +besucht +aufwärts +dynamisch +Sahne +viel +Teufel +Gebrauchsanweisung +Gradido +sieben +Flucht +holen +baden +ändern +jüngeren +Natur +chinesisch +Rohmaterial +Hauch +Konkurrenz +fiktiv +akkumulieren +Ball +beenden +bemüht +recyclebar +gedruckt +vegetarisch +woran +erwerben +lasst +bleiben +Radfahrer +Bücher +Klavier +genannt +Quelle +erheblich +gegenseitig +abzahlen +stagnieren +Hubert +Ende +Crash +Trinkwasser +Franz +Insekt +sensibilisieren +Erneuerung +Sehnen +Maus +Frau +betonung +stiege +Porsche +beide +absurd +dato +Österreich +beteiligen +dies +gezwungen +anvertrauen +Tilgung +Feder +logisch +konventionell +fatal +kulinarisch +Abholzung +Cicero +nostalgischen +schützen +brachte +Metzger +geehrt +Flasche +bringt +Villa +Krise +bietet +Entlastung +ausführung +Wikipedia +stellen +Park +Video +Papiergeld +voll +inzwischen +Jäger +Topf +ülzen +umgekehrt +Hanf +Februar +zirkulieren +John +heben +Novellierung +unfähig +servieren +Meier +jeweilig +Heuschrecke +daher +Alexander +Peter +erkannt +Gehirn +lateinisch +anpassbar +anderen +Artikel +Wucht +Leben +sein +exzellent +beantworten +Asche +reduzieren +Hersteller +Victor +zumal +Plage +hassen +fünf +liebevoll +für +Acker +morphogenetisch +Sachverhalt +umpolen +gibt +Busfahrer +beherzigen +weitergeben +brav +jeder +sich +Galaxis +steht +Maschine +erzielen +Sanierung +Kraft +Netto +Begabung +ersetzen +mindest +gestorben +Osten +Gebiet +Zweifel +zugleich +wild +kameradschaftlich +Farbe +Mitmensch +bevölkern +gesamt +Mittel +Reporter +Kilometer +kostenlos +mobil +wehren +herunter +Ansehen +erfrischend +Hotel +Analyse +Griechisch +Abwurf +käuflich +Bernd +entgegengesetzt +Bewusstsein +ankaufen +zurzeit +Impressum +Toast +Ladung +Verfütterung +Form +Wasser +gesund +noch +horchen +Variante +Anleitung +Pazifik +Wiederherstellung +Wandel +transformieren +Tisch +verknappt +Material +Realisierung +einer +Daimler +unvorstellbar +meldete +Strickmuster +stammen +Menge +Verifizieren +tief +Puzzle +Gepflogenheit +Ziel +dürfen +doch +Sinn +Region +fangen +zuteil +Anspruch +kehrte +Freund +Fimmel +darum +Girokonto +Zweck +Wohngemeinschaft +Projekt +schweigen +Kupfer +tauchen +holzig +Tendenz +abhalten +Nummer +bald +Töne +Salvador +Kapitel +Ibiza +Komfort +wobei +lachen +Wagnis +metaphorisch +gelb +bevor +unnatürlich +Leasing +bemerkenswert +zugute +beruhen +soeben +Kopf +wischen +appellieren +gelten +statt +Futter +Erdball +benötigt +futsch +Symbol +wofür +Glanz +beispiellos +normalen +mitfinanzieren +Frucht +italienisch +woher +allzu +beleben +weigern +Senf +Gift +atemlos +Cäsar +Begegnung +horten +sobald +Luxus +biologisch +Wettbewerb +Umkehrschluss +fallen +Darlehen +klug +anpreisen +doppelt +abwechslungsreich +Werner +nannte +Wittenberg +existenzbedrohend +deren +zynisch +Feuer +Leistung +Ideologie +Enkel +diskutiert +pervers +Brot +Ordnung +blubbern +einander +College +folgen +Anreiz +Agrarfläche +aufdecken +zerrinnen +ergründen +spalten +unehelich +Experte +viertel +gezogen +Mitspieler +geklappt +Kette +Petrus +Nahrung +Georg +Patent +Unkenntlich +Waage +ernähren +Botschafter +hell +Zelle +Silbe +pfiffig +Mystisch +Acht +ahnen +erkämpft +Team +zunächst +Benzin +falsch +erwarten +raffen +Auflage +Thema +ernten +Monat +lindern +meisten +zurückerlangen +Fenster +unabhängig +Jesus +geistig +divers +Göttingen +unruhig +Kategorie +fassen +hinzu +Wachstum +Sven +Chemie +quälen +Herde +standen +jährlich +Anhang +nötig +Hirsch +derjenige +Kurzgeschichte +ökologische +Theater +willkommen +ausüben +Kanal +nennt +Name +wussten +drücken +aufnehmen +Äste +Rücken +intuition +hätte +Zunahme +Gläubiger +abzählen +Phänomen +Ablage +spontan +spannend +Vanessa +Asien +gewusst +elektronisch +derb +getilgt +Antwort +geeignet +Bote +gequält +Anerkennung +Bilanz +natürlich +machbar +Verpackung +Blut +Eltern +Himbeere +rumfliegen +Senioren +zwingen +Spitze +Taschendiebe +steckt +Monster +Egotrip +Helmut +Bibel +geerbt +zitieren +Ameisenbau +Rekordgewinne +Hände +ergänzen +danach +orden +hinter +wenn +paddeln +gutes +Hinsicht +wegen +Teilhabe +Gesellschaft +christlich +Bezugsquelle +Igor +ausprobieren +Endpreis +links +gekürzt +einkaufen +Lied +Gerhard +gelohnt +nackt +Geburt +gelehrt +einseitig +gedeckt +hinweg +Eduard +Premiere +demografisch +ihre +höchste +wichtigsten +Aufmerksamkeit +Horde +physisch +Arbeitsklima +Brief +Notdurft +proportional +fordern +Ewig +denken +Daniel +Arabisch +edle +golden +Minimum +pure +beibringen +Boden +Anzahl +erschaffen +Energie +sehr +Gerücht +Generation +Räuber +Motivation +Chance +dabei +Programm +segensreich +April +ignorieren +Nase +epochal +Boot +faszinieren +Heilkunde +Helikopter +Computer +Kabarettist +wenig +zukünftig +sechzehn +stimmt +getragen +reagieren +Esoterik +Koralle +Dame +Katastrophe +liefern +Grund +Elend +ausreichen +Notenbank +Garten +zutiefst +Immobilien +Aspekt +naiv +besprechen +zählen +Terminologie +Amerika +Atmosphäre +Iran +debatte +Sound +Zugang +fair +unrentabel +baut +kollektiv +schief +Bank +Mann +Apropos +Ergebnis +Niederlande +Mietshaus +errichten +Ereignis +Portal +erhielten +erleben +Haus +Dschungel +Null +Pleite +Seegras +Entdeckung +also +Ebene +Anbeginn +kohärent +Autor +Mensch +hielt +Reich +Land +bekloppt +außerdem +Berg +gleich +sind +Argument +einverstanden +Euro +Sektor +dagegen +Knappheit +Armut +innerhalb +Blume +Problem +Bruder +Netzwerk +Orte +bedrängen +Aufgabe From 20c440c2580e6085967a35491fff9d138234dc53 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 2 Nov 2021 17:21:57 +0100 Subject: [PATCH 13/47] Changed the save methods used on entities to repository save entity methods. --- backend/src/graphql/resolver/UserResolver.ts | 23 +++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 65945d668..769da6bdf 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -35,6 +35,8 @@ import { CheckEmailResponse } from '../model/CheckEmailResponse' import { UserSettingRepository } from '../../typeorm/repository/UserSettingRepository' import { Setting } from '../enum/Setting' import { UserRepository } from '../../typeorm/repository/User' +import { LoginUserRepository } from '../../typeorm/repository/LoginUser' +import { LoginUserBackupRepository } from '../../typeorm/repository/LoginUserBackup' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { bigintToBuf } from 'bigint-conversion' @@ -118,7 +120,8 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { } const generateKeys = async (email: string): Promise => { - const mNewUser = await LoginUser.findOneOrFail({ email }) + const loginUserRepository = getCustomRepository(LoginUserRepository) + const mNewUser = await loginUserRepository.findOneOrFail({ email }) // TODO figure mnemonic database // const lang = mNewUser.language /* @@ -134,7 +137,8 @@ const generateKeys = async (email: string): Promise => { loginUserBackup.passphrase = passphrase.join(' ') loginUserBackup.mnemonicType = 2 // ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; - await loginUserBackup.save().catch(() => { + const loginUserBackupRepository = getCustomRepository(LoginUserBackupRepository) + await loginUserBackupRepository.save(loginUserBackup).catch(() => { throw new Error('insert user backup failed') }) @@ -144,7 +148,7 @@ const generateKeys = async (email: string): Promise => { mNewUser.pubKey = gradidoKeyPair[0] mNewUser.privKey = gradidoKeyPair[1] - await mNewUser.save().catch(() => { + await loginUserRepository.save(mNewUser).catch(() => { throw new Error(`Error saving new generated pub/priv keys, email: ${email}`) }) @@ -188,7 +192,7 @@ export class UserResolver { userEntity.email = user.email userEntity.pubkey = Buffer.from(user.pubkey, 'hex') - userEntity.save().catch(() => { + userRepository.save(userEntity).catch(() => { throw new Error('error by save userEntity') }) }) @@ -271,7 +275,8 @@ export class UserResolver { // Validate email unique // TODO: i can register an email in upper/lower case twice - const usersFound = await LoginUser.count({ email }) + const userRepository = getCustomRepository(UserRepository) + const usersFound = await userRepository.count({ email }) if (usersFound !== 0) { // 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. throw new Error(`User already exists.`) @@ -291,8 +296,10 @@ export class UserResolver { loginUser.publisherId = publisherId // TODO: check if this insert method is correct, we had problems with that! - await loginUser.save().catch(() => { + const loginUserRepository = getCustomRepository(LoginUserRepository) + await loginUserRepository.save(loginUser).catch((error) => { // TODO: this triggered an EMail send + console.log('insert user failed', error) throw new Error('insert user failed') }) @@ -324,7 +331,7 @@ export class UserResolver { dbuser.lastName = lastName dbuser.username = username - await dbuser.save().catch(() => { + await userRepository.save(dbuser).catch(() => { throw new Error('error saving user') }) @@ -426,7 +433,7 @@ export class UserResolver { userEntityChanged = true } if (userEntityChanged) { - userEntity.save().catch((error) => { + userRepository.save(userEntity).catch((error) => { throw new Error(error) }) } From d286d687309f9b4046a083b7de0a6be222862679 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 2 Nov 2021 17:24:45 +0100 Subject: [PATCH 14/47] Create the LoginUserRepository. --- backend/src/typeorm/repository/LoginUser.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 backend/src/typeorm/repository/LoginUser.ts diff --git a/backend/src/typeorm/repository/LoginUser.ts b/backend/src/typeorm/repository/LoginUser.ts new file mode 100644 index 000000000..e69de29bb From 5220874a0795e14b9ef2e12a7e80fffed6761ee2 Mon Sep 17 00:00:00 2001 From: elweyn Date: Tue, 2 Nov 2021 17:27:09 +0100 Subject: [PATCH 15/47] Setup LoginUserBackupRepository. --- backend/src/typeorm/repository/LoginUser.ts | 5 +++++ backend/src/typeorm/repository/LoginUserBackup.ts | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 backend/src/typeorm/repository/LoginUserBackup.ts diff --git a/backend/src/typeorm/repository/LoginUser.ts b/backend/src/typeorm/repository/LoginUser.ts index e69de29bb..d0db007d0 100644 --- a/backend/src/typeorm/repository/LoginUser.ts +++ b/backend/src/typeorm/repository/LoginUser.ts @@ -0,0 +1,5 @@ +import { EntityRepository, Repository } from 'typeorm' +import { LoginUser } from '@entity/LoginUser' + +@EntityRepository(LoginUser) +export class LoginUserRepository extends Repository {} diff --git a/backend/src/typeorm/repository/LoginUserBackup.ts b/backend/src/typeorm/repository/LoginUserBackup.ts new file mode 100644 index 000000000..8c729139a --- /dev/null +++ b/backend/src/typeorm/repository/LoginUserBackup.ts @@ -0,0 +1,5 @@ +import { EntityRepository, Repository } from 'typeorm' +import { LoginUserBackup } from '@entity/LoginUserBackup' + +@EntityRepository(LoginUserBackup) +export class LoginUserBackupRepository extends Repository {} From 7a36d97835b83c023e1a6b7833a7eea82427eede Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 2 Nov 2021 21:17:00 +0100 Subject: [PATCH 16/47] lint fixes, disabled console lint, removed email todo since its logged - should be adequat --- backend/src/graphql/resolver/UserResolver.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 769da6bdf..c883cbb39 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -13,7 +13,7 @@ import { crypto_sign_SECRETKEYBYTES, /* eslint-enable camelcase */ } from 'sodium-native' -import { getCustomRepository, NoNeedToReleaseEntityManagerError } from 'typeorm' +import { getCustomRepository } from 'typeorm' import CONFIG from '../../config' import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode' import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse' @@ -298,7 +298,7 @@ export class UserResolver { // TODO: check if this insert method is correct, we had problems with that! const loginUserRepository = getCustomRepository(LoginUserRepository) await loginUserRepository.save(loginUser).catch((error) => { - // TODO: this triggered an EMail send + // eslint-disable-next-line no-console console.log('insert user failed', error) throw new Error('insert user failed') }) From c6af40d1bd90ce30abf523a8cf591ebd2c7d79e2 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 00:51:26 +0100 Subject: [PATCH 17/47] we connot use those types, they are wrong --- backend/package.json | 1 - backend/yarn.lock | 7 ------- 2 files changed, 8 deletions(-) diff --git a/backend/package.json b/backend/package.json index c3fec6983..b80120cb0 100644 --- a/backend/package.json +++ b/backend/package.json @@ -38,7 +38,6 @@ "devDependencies": { "@types/express": "^4.17.12", "@types/jsonwebtoken": "^8.5.2", - "@types/sodium-native": "^2.3.5", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", "eslint": "^7.29.0", diff --git a/backend/yarn.lock b/backend/yarn.lock index 92c679039..da6a37950 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -951,13 +951,6 @@ "@types/mime" "^1" "@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": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" From 2473f450c34ce6dc49ce8a3248f62bbf2e8bc532 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 00:51:55 +0100 Subject: [PATCH 18/47] - require sodium because else problems occur - fix key generation --- backend/src/graphql/resolver/UserResolver.ts | 79 +++++++++++++++----- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index c883cbb39..1ff60d769 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -3,16 +3,17 @@ import fs from 'fs' import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql' -import { - /* eslint-disable camelcase */ - randombytes_random, - crypto_hash_sha512_instance, - crypto_hash_sha512_BYTES, - crypto_sign_seed_keypair, - crypto_sign_PUBLICKEYBYTES, - crypto_sign_SECRETKEYBYTES, - /* eslint-enable camelcase */ -} from 'sodium-native' +// import { +// /* eslint-disable camelcase */ +// randombytes_random, +// crypto_hash_sha512_instance, +// crypto_hash_sha512_BYTES, +// crypto_sign_seed_keypair, +// crypto_sign_PUBLICKEYBYTES, +// crypto_sign_SECRETKEYBYTES, +// /* eslint-enable camelcase */ +// } from 'sodium-native' + import { getCustomRepository } from 'typeorm' import CONFIG from '../../config' import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode' @@ -41,6 +42,9 @@ import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { bigintToBuf } from 'bigint-conversion' +// eslint-disable-next-line @typescript-eslint/no-var-requires +const sodium = require('sodium-native') + // We will reuse this for changePassword const isPassword = (password: string): boolean => { if (!password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9 \\t\\n\\r]).{8,}$/)) { @@ -79,11 +83,42 @@ const WORDS = fs.readFileSync('src/config/mnemonic.english.txt').toString().spli const PassphraseGenerate = (): string[] => { const result = [] for (let i = 0; i < PHRASE_WORD_COUNT; i++) { - result.push(WORDS[randombytes_random() % 2048]) + result.push(WORDS[sodium.randombytes_random() % 2048]) } return result } +/* + return [ + 'avoid', + 'security', + 'heavy', + 'mercy', + 'exit', + 'avocado', + 'actress', + 'apple', + 'crowd', + 'drop', + 'rib', + 'photo', + 'valley', + 'test', + 'board', + 'evidence', + 'blast', + 'pencil', + 'frost', + 'frame', + 'come', + 'vanish', + 'very', + 'inner', + ] +*/ +// pub: 0xdd1b7bb +// priv: 0xbcadd66 + const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { if (!passphrase.length || passphrase.length < PHRASE_WORD_COUNT) { throw new Error('passphrase empty or to short') @@ -98,23 +133,29 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { // if (!wordIndicies || (!wordIndicies[0] && !wordIndicies[1] && !wordIndicies[2] && !wordIndicies[3])) { // return null; // } + const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES) - const hash = crypto_hash_sha512_instance() + // sodium.crypto_hash_sha256_init(state /* , [key], outlen */) + sodium.crypto_hash_sha512_init(state) // To prevent breaking existing passphrase-hash combinations word indices will be put into 64 Bit Variable to mimic first implementation of algorithms for (let i = 0; i < PHRASE_WORD_COUNT; i++) { const value = BigInt(wordIndicies[i]) - hash.update(Buffer.from(bigintToBuf(value))) + sodium.crypto_hash_sha512_update(state, Buffer.from(bigintToBuf(value))) // hash.update(Buffer.from(bigintToBuf(value))) } const clearPassphrase = passphrase.join(' ') - hash.update(Buffer.from(clearPassphrase)) - const outputHashBuffer = Buffer.alloc(crypto_hash_sha512_BYTES) - hash.final(outputHashBuffer) + sodium.crypto_hash_sha512_update(state, Buffer.from(clearPassphrase)) // hash.update(Buffer.from(clearPassphrase)) + const outputHashBuffer = Buffer.alloc(sodium.crypto_hash_sha512_BYTES) + sodium.crypto_hash_sha512_final(state, outputHashBuffer) // hash.final(outputHashBuffer) - const pubKey = Buffer.alloc(crypto_sign_PUBLICKEYBYTES) - const privKey = Buffer.alloc(crypto_sign_SECRETKEYBYTES) + const pubKey = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES) + const privKey = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES) - crypto_sign_seed_keypair(pubKey, privKey, outputHashBuffer) + sodium.crypto_sign_seed_keypair( + pubKey, + privKey, + outputHashBuffer.slice(sodium.crypto_sign_SEEDBYTES), + ) return [pubKey, privKey] } From 5736d3ba0b7c90b2ec4d871e4ad365a31dd558a0 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 02:08:10 +0100 Subject: [PATCH 19/47] removed bigint-conversion, fixed keygeneration to be aligned 100% with login_server trailing space on passphrase bigint to hash conversion --- backend/package.json | 1 - backend/src/graphql/resolver/UserResolver.ts | 23 +++++++++++--------- backend/yarn.lock | 12 ---------- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/backend/package.json b/backend/package.json index b80120cb0..ee7365b72 100644 --- a/backend/package.json +++ b/backend/package.json @@ -19,7 +19,6 @@ "@types/jest": "^27.0.2", "apollo-server-express": "^2.25.2", "axios": "^0.21.1", - "bigint-conversion": "^2.2.1", "class-validator": "^0.13.1", "cors": "^2.8.5", "dotenv": "^10.0.0", diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 1ff60d769..2f4fe93cf 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -40,8 +40,8 @@ import { LoginUserRepository } from '../../typeorm/repository/LoginUser' import { LoginUserBackupRepository } from '../../typeorm/repository/LoginUserBackup' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' -import { bigintToBuf } from 'bigint-conversion' +// TODO apparently the types are cannot be loaded correctly? IDK whats wrong and we have to use require // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') @@ -117,7 +117,7 @@ const PassphraseGenerate = (): string[] => { ] */ // pub: 0xdd1b7bb -// priv: 0xbcadd66 +// priv: 0xbcadd66 (wrong?) const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { if (!passphrase.length || passphrase.length < PHRASE_WORD_COUNT) { @@ -129,24 +129,27 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { wordIndicies.push(WORDS.indexOf(passphrase[i])) } + // eslint-disable-next-line no-console + console.log(wordIndicies) // TODO: wtf is this? // if (!wordIndicies || (!wordIndicies[0] && !wordIndicies[1] && !wordIndicies[2] && !wordIndicies[3])) { // return null; // } - const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES) - // sodium.crypto_hash_sha256_init(state /* , [key], outlen */) + const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES) sodium.crypto_hash_sha512_init(state) // To prevent breaking existing passphrase-hash combinations word indices will be put into 64 Bit Variable to mimic first implementation of algorithms for (let i = 0; i < PHRASE_WORD_COUNT; i++) { - const value = BigInt(wordIndicies[i]) - sodium.crypto_hash_sha512_update(state, Buffer.from(bigintToBuf(value))) // hash.update(Buffer.from(bigintToBuf(value))) + const value = Buffer.alloc(8) + value.writeBigInt64LE(BigInt(wordIndicies[i])) + sodium.crypto_hash_sha512_update(state, value) } - const clearPassphrase = passphrase.join(' ') - sodium.crypto_hash_sha512_update(state, Buffer.from(clearPassphrase)) // hash.update(Buffer.from(clearPassphrase)) + // TODO trailing space in login_server + const clearPassphrase = passphrase.join(' ') + ' ' + sodium.crypto_hash_sha512_update(state, Buffer.from(clearPassphrase)) const outputHashBuffer = Buffer.alloc(sodium.crypto_hash_sha512_BYTES) - sodium.crypto_hash_sha512_final(state, outputHashBuffer) // hash.final(outputHashBuffer) + sodium.crypto_hash_sha512_final(state, outputHashBuffer) const pubKey = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES) const privKey = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES) @@ -154,7 +157,7 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { sodium.crypto_sign_seed_keypair( pubKey, privKey, - outputHashBuffer.slice(sodium.crypto_sign_SEEDBYTES), + outputHashBuffer.slice(0, sodium.crypto_sign_SEEDBYTES), ) return [pubKey, privKey] diff --git a/backend/yarn.lock b/backend/yarn.lock index da6a37950..7cd146647 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -562,11 +562,6 @@ resolved "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz" integrity sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg== -"@juanelas/base64@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@juanelas/base64/-/base64-1.0.1.tgz#aaede00ffdca595741fc69d0008b4cfc8f08293a" - integrity sha512-ZK/wWrjMrrMcprtOV72iilC1M/HfZcF2JeUJPHOL0tMm1TZrh9UhHDQEdPny/MmmT7tO4w47ycuy0YTnBrS5fg== - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -1512,13 +1507,6 @@ base64-js@^1.3.1: resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -bigint-conversion@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/bigint-conversion/-/bigint-conversion-2.2.1.tgz#08c9f17a826943c7e56d4bfa9f0fc7fe8050a940" - integrity sha512-9TvqpV+VZ04fPKv4KPLQRk5ZAFhgHX4F7bYQY263/BbJBFzEGbtBeTQV9oNuAGaqj88PXdov1OcSNQtq9K9MPA== - dependencies: - "@juanelas/base64" "^1.0.1" - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" From d4e0815d0068d817c9261b34992bfaf9b404c0f6 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 02:51:34 +0100 Subject: [PATCH 20/47] cleaned the whole thing --- backend/src/graphql/resolver/UserResolver.ts | 135 ++++++------------- 1 file changed, 44 insertions(+), 91 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 2f4fe93cf..61951cec1 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -3,17 +3,6 @@ import fs from 'fs' import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql' -// import { -// /* eslint-disable camelcase */ -// randombytes_random, -// crypto_hash_sha512_instance, -// crypto_hash_sha512_BYTES, -// crypto_sign_seed_keypair, -// crypto_sign_PUBLICKEYBYTES, -// crypto_sign_SECRETKEYBYTES, -// /* eslint-enable camelcase */ -// } from 'sodium-native' - import { getCustomRepository } from 'typeorm' import CONFIG from '../../config' import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode' @@ -42,38 +31,26 @@ import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' // TODO apparently the types are cannot be loaded correctly? IDK whats wrong and we have to use require +// import { +// /* eslint-disable camelcase */ +// randombytes_random, +// crypto_hash_sha512_instance, +// crypto_hash_sha512_BYTES, +// crypto_sign_seed_keypair, +// crypto_sign_PUBLICKEYBYTES, +// crypto_sign_SECRETKEYBYTES, +// /* eslint-enable camelcase */ +// } from 'sodium-native' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') // We will reuse this for changePassword const isPassword = (password: string): boolean => { - if (!password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9 \\t\\n\\r]).{8,}$/)) { - return false - // TODO we dont need this right, frontend does it? - /* - if(pwd.length < 8){ - throw new Error('Your password is to short!') - } - if(!pwd.match(/[a-z]/)){ - throw new Error('Your password does not contain lowercase letters!') - } - if(!pwd.match(/[A-Z]/)){ - throw new Error('Your password does not contain any capital letters!') - } - if(!pwd.match(/[0-9]/)){ - throw new Error('Your password does not contain any number!') - } - if(!pwd.match(/[^a-zA-Z0-9 \\t\\n\\r]/)){ - throw new Error('Your password does not contain special characters!') - } - */ - } - return true + return !!password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9 \\t\\n\\r]).{8,}$/) } const LANGUAGES = ['de', 'en'] const DEFAULT_LANGUAGE = 'de' -// very likely to be reused const isLanguage = (language: string): boolean => { return LANGUAGES.includes(language) } @@ -131,10 +108,6 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { // eslint-disable-next-line no-console console.log(wordIndicies) - // TODO: wtf is this? - // if (!wordIndicies || (!wordIndicies[0] && !wordIndicies[1] && !wordIndicies[2] && !wordIndicies[3])) { - // return null; - // } const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES) sodium.crypto_hash_sha512_init(state) @@ -163,42 +136,6 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { return [pubKey, privKey] } -const generateKeys = async (email: string): Promise => { - const loginUserRepository = getCustomRepository(LoginUserRepository) - const mNewUser = await loginUserRepository.findOneOrFail({ email }) - // TODO figure mnemonic database - // const lang = mNewUser.language - /* - if (LANG_DE == lang) { - mnemonic_type = ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES; - } - */ - - const passphrase = PassphraseGenerate() - - const loginUserBackup = new LoginUserBackup() - loginUserBackup.userId = mNewUser.id - loginUserBackup.passphrase = passphrase.join(' ') - loginUserBackup.mnemonicType = 2 // ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; - - const loginUserBackupRepository = getCustomRepository(LoginUserBackupRepository) - await loginUserBackupRepository.save(loginUserBackup).catch(() => { - throw new Error('insert user backup failed') - }) - - // keys - const gradidoKeyPair = KeyPairEd25519Create(passphrase) - - mNewUser.pubKey = gradidoKeyPair[0] - mNewUser.privKey = gradidoKeyPair[1] - - await loginUserRepository.save(mNewUser).catch(() => { - throw new Error(`Error saving new generated pub/priv keys, email: ${email}`) - }) - - return gradidoKeyPair -} - @Resolver() export class UserResolver { @Query(() => User) @@ -326,30 +263,59 @@ export class UserResolver { throw new Error(`User already exists.`) } + const passphrase = PassphraseGenerate() + const keyPair = KeyPairEd25519Create(passphrase) + + // Table: login_users const loginUser = new LoginUser() loginUser.email = email loginUser.firstName = firstName loginUser.lastName = lastName loginUser.username = username loginUser.description = '' + // TODO password? loginUser.password = BigInt(0) // TODO: This was never used according to my analysis. Therefore I consider it safe to set to 0 loginUser.emailHash = Buffer.from([0]) loginUser.language = language loginUser.groupId = 1 loginUser.publisherId = publisherId + loginUser.pubKey = keyPair[0] + loginUser.privKey = keyPair[1] - // TODO: check if this insert method is correct, we had problems with that! + // TODO transaction const loginUserRepository = getCustomRepository(LoginUserRepository) - await loginUserRepository.save(loginUser).catch((error) => { + const { id: loginUserId } = await loginUserRepository.save(loginUser).catch((error) => { // eslint-disable-next-line no-console console.log('insert user failed', error) throw new Error('insert user failed') }) - const keys = await generateKeys(email) - const pubkey = keys[0] + // Table: login_user_backups + const loginUserBackup = new LoginUserBackup() + loginUserBackup.userId = loginUserId + loginUserBackup.passphrase = passphrase.join(' ') + loginUserBackup.mnemonicType = 2 // ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; + // TODO transaction + const loginUserBackupRepository = getCustomRepository(LoginUserBackupRepository) + await loginUserBackupRepository.save(loginUserBackup).catch(() => { + throw new Error('insert user backup failed') + }) + + // Table: state_users + const dbuser = new DbUser() + dbuser.pubkey = keyPair[0] + dbuser.email = email + dbuser.firstName = firstName + dbuser.lastName = lastName + dbuser.username = username + + await userRepository.save(dbuser).catch(() => { + throw new Error('error saving user') + }) + + // TODO this is the password encryption // TODO: we do not login the user as before, since session management is not yet ported // calculate encryption key, could need some time, will save encrypted privkey to db // UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(user, password); @@ -366,19 +332,6 @@ export class UserResolver { // emailOptIn->setBaseUrl(user->getGroupBaseUrl() + ServerConfig::g_frontend_checkEmailPath); // em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); - // ------------------------------------------------------ - - const dbuser = new DbUser() - dbuser.pubkey = pubkey - dbuser.email = email - dbuser.firstName = firstName - dbuser.lastName = lastName - dbuser.username = username - - await userRepository.save(dbuser).catch(() => { - throw new Error('error saving user') - }) - return 'success' } From ff0388c82c05d944823dc25e385009c40ecf32bf Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 02:57:25 +0100 Subject: [PATCH 21/47] typo --- backend/src/graphql/resolver/UserResolver.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 61951cec1..32272fbda 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -304,14 +304,14 @@ export class UserResolver { }) // Table: state_users - const dbuser = new DbUser() - dbuser.pubkey = keyPair[0] - dbuser.email = email - dbuser.firstName = firstName - dbuser.lastName = lastName - dbuser.username = username + const dbUser = new DbUser() + dbUser.pubkey = keyPair[0] + dbUser.email = email + dbUser.firstName = firstName + dbUser.lastName = lastName + dbUser.username = username - await userRepository.save(dbuser).catch(() => { + await userRepository.save(dbUser).catch(() => { throw new Error('error saving user') }) From 30455fd22077d84c2e0822f38207494720d4e0cc Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 03:08:53 +0100 Subject: [PATCH 22/47] missing todo --- backend/src/graphql/resolver/UserResolver.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 32272fbda..a07c944ae 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -311,6 +311,7 @@ export class UserResolver { dbUser.lastName = lastName dbUser.username = username + // TDOO transaction await userRepository.save(dbUser).catch(() => { throw new Error('error saving user') }) From 2381c3dd7a705c202984261c450f7039a2c33ac9 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 04:39:57 +0100 Subject: [PATCH 23/47] generate password hash --- backend/src/graphql/resolver/UserResolver.ts | 50 ++++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a07c944ae..f525e233a 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -136,6 +136,42 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { return [pubKey, privKey] } +const SecretKeyCryptographyCreateKey = (salt: string, password: string): Buffer[] => { + // TODO: put that in the actual config + const configCryptoAppSecret = Buffer.from('21ffbbc616fe', 'hex') + const configCryptoServerKey = Buffer.from('a51ef8ac7ef1abf162fb7a65261acd7a', 'hex') + if (configCryptoServerKey.length !== sodium.crypto_shorthash_KEYBYTES) { + throw new Error( + `ServerKey has an invalid size. The size must be ${sodium.crypto_shorthash_KEYBYTES} bytes.`, + ) + } + + const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES) + sodium.crypto_hash_sha512_init(state) + sodium.crypto_hash_sha512_update(state, Buffer.from(salt)) + sodium.crypto_hash_sha512_update(state, Buffer.from(configCryptoAppSecret)) + const hash = Buffer.alloc(sodium.crypto_hash_sha512_BYTES) + sodium.crypto_hash_sha512_final(state, hash) + + const encryptionKey = Buffer.alloc(sodium.crypto_box_SEEDBYTES) + const opsLimit = 10 + const memLimit = 33554432 + const algo = 2 + sodium.crypto_pwhash( + encryptionKey, + Buffer.from(password), + hash.slice(0, sodium.crypto_pwhash_SALTBYTES), + opsLimit, + memLimit, + algo, + ) + + const encryptionKeyHash = Buffer.alloc(sodium.crypto_shorthash_BYTES) + sodium.crypto_shorthash(encryptionKeyHash, encryptionKey, configCryptoServerKey) + + return [encryptionKeyHash, encryptionKey] +} + @Resolver() export class UserResolver { @Query(() => User) @@ -265,6 +301,7 @@ export class UserResolver { const passphrase = PassphraseGenerate() const keyPair = KeyPairEd25519Create(passphrase) + const passwordHash = SecretKeyCryptographyCreateKey(email, password) // Table: login_users const loginUser = new LoginUser() @@ -273,9 +310,10 @@ export class UserResolver { loginUser.lastName = lastName loginUser.username = username loginUser.description = '' - // TODO password? - loginUser.password = BigInt(0) - // TODO: This was never used according to my analysis. Therefore I consider it safe to set to 0 + loginUser.password = passwordHash[0].readBigUInt64LE() // using the shorthash + // TODO: This was never used according to my analysis. Therefore I consider it + // safe to set to 0, since we can generate it whenever we need it, assuming + // that its actually the email hash and the password is not involved loginUser.emailHash = Buffer.from([0]) loginUser.language = language loginUser.groupId = 1 @@ -316,12 +354,6 @@ export class UserResolver { throw new Error('error saving user') }) - // TODO this is the password encryption - // TODO: we do not login the user as before, since session management is not yet ported - // calculate encryption key, could need some time, will save encrypted privkey to db - // UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(user, password); - // create_authenticated_encrypten_key->scheduleTask(create_authenticated_encrypten_key); - // TODO: send EMail (EMAIL_OPT_IN_REGISTER) // const emailType = 2 // auto emailOptIn = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); From 8ed4ade3fe97efcf7ddd1b62a79c9303521fb3c0 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 04:44:42 +0100 Subject: [PATCH 24/47] finished todo --- backend/src/graphql/resolver/UserResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f525e233a..8aabf0cc3 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -118,7 +118,7 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { value.writeBigInt64LE(BigInt(wordIndicies[i])) sodium.crypto_hash_sha512_update(state, value) } - // TODO trailing space in login_server + // trailing space is part of the login_server implementation const clearPassphrase = passphrase.join(' ') + ' ' sodium.crypto_hash_sha512_update(state, Buffer.from(clearPassphrase)) const outputHashBuffer = Buffer.alloc(sodium.crypto_hash_sha512_BYTES) From 86fbe1d11c15d1606d0e0cb2a2a64e18084bbfdb Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 04:59:25 +0100 Subject: [PATCH 25/47] generate email hash --- backend/src/graphql/resolver/UserResolver.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 8aabf0cc3..7688f3766 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -172,6 +172,13 @@ const SecretKeyCryptographyCreateKey = (salt: string, password: string): Buffer[ return [encryptionKeyHash, encryptionKey] } +const getEmailHash = (email:string):Buffer => +{ + const emailHash = Buffer.alloc(sodium.crypto_generichash_BYTES) + sodium.crypto_generichash(emailHash,Buffer.from(email)); + return emailHash +} + @Resolver() export class UserResolver { @Query(() => User) @@ -302,6 +309,7 @@ export class UserResolver { const passphrase = PassphraseGenerate() const keyPair = KeyPairEd25519Create(passphrase) const passwordHash = SecretKeyCryptographyCreateKey(email, password) + const emailHash = getEmailHash(email) // Table: login_users const loginUser = new LoginUser() @@ -311,10 +319,7 @@ export class UserResolver { loginUser.username = username loginUser.description = '' loginUser.password = passwordHash[0].readBigUInt64LE() // using the shorthash - // TODO: This was never used according to my analysis. Therefore I consider it - // safe to set to 0, since we can generate it whenever we need it, assuming - // that its actually the email hash and the password is not involved - loginUser.emailHash = Buffer.from([0]) + loginUser.emailHash = emailHash loginUser.language = language loginUser.groupId = 1 loginUser.publisherId = publisherId From 02ce432dc5cb6d72642d40ef862896de3fb64e8a Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 05:08:05 +0100 Subject: [PATCH 26/47] lint, removed console, removed todo --- backend/src/graphql/resolver/UserResolver.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 7688f3766..b80b202a1 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -106,9 +106,6 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { wordIndicies.push(WORDS.indexOf(passphrase[i])) } - // eslint-disable-next-line no-console - console.log(wordIndicies) - const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES) sodium.crypto_hash_sha512_init(state) @@ -172,10 +169,9 @@ const SecretKeyCryptographyCreateKey = (salt: string, password: string): Buffer[ return [encryptionKeyHash, encryptionKey] } -const getEmailHash = (email:string):Buffer => -{ +const getEmailHash = (email: string): Buffer => { const emailHash = Buffer.alloc(sodium.crypto_generichash_BYTES) - sodium.crypto_generichash(emailHash,Buffer.from(email)); + sodium.crypto_generichash(emailHash, Buffer.from(email)) return emailHash } @@ -284,7 +280,6 @@ export class UserResolver { } // Validate Password - // TODO Login Server ignored this when he got an empty password?! if (!isPassword(password)) { throw new Error( 'Please enter a valid password with at least 8 characters, upper and lower case letters, at least one number and one special character!', From f7f0d9821928114bdc5db6b494096e6594dac7c0 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 3 Nov 2021 09:41:57 +0100 Subject: [PATCH 27/47] Optimise code, withdrew loop and integrated the logic in the second loop. --- backend/src/graphql/resolver/UserResolver.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index b80b202a1..b80e69c8e 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -101,18 +101,14 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { throw new Error('passphrase empty or to short') } - const wordIndicies = [] - for (let i = 0; i < PHRASE_WORD_COUNT; i++) { - wordIndicies.push(WORDS.indexOf(passphrase[i])) - } - const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES) sodium.crypto_hash_sha512_init(state) // To prevent breaking existing passphrase-hash combinations word indices will be put into 64 Bit Variable to mimic first implementation of algorithms for (let i = 0; i < PHRASE_WORD_COUNT; i++) { const value = Buffer.alloc(8) - value.writeBigInt64LE(BigInt(wordIndicies[i])) + const wordIndex = WORDS.indexOf(passphrase[i]) + value.writeBigInt64LE(BigInt(wordIndex)) sodium.crypto_hash_sha512_update(state, value) } // trailing space is part of the login_server implementation @@ -350,7 +346,9 @@ export class UserResolver { dbUser.username = username // TDOO transaction - await userRepository.save(dbUser).catch(() => { + await userRepository.save(dbUser).catch((er) => { + // eslint-disable-next-line no-console + console.log('Error while saving dbUser', er) throw new Error('error saving user') }) From 3fcedaec4182d5e0ddc1bb402fd3e8e5cd005383 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 20:52:30 +0100 Subject: [PATCH 28/47] encrypt private key --- backend/src/graphql/resolver/UserResolver.ts | 27 ++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index b80e69c8e..dbe1aa6fa 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -63,9 +63,7 @@ const PassphraseGenerate = (): string[] => { result.push(WORDS[sodium.randombytes_random() % 2048]) } return result -} - -/* + /* return [ 'avoid', 'security', @@ -92,9 +90,8 @@ const PassphraseGenerate = (): string[] => { 'very', 'inner', ] -*/ -// pub: 0xdd1b7bb -// priv: 0xbcadd66 (wrong?) + */ +} const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { if (!passphrase.length || passphrase.length < PHRASE_WORD_COUNT) { @@ -171,6 +168,15 @@ const getEmailHash = (email: string): Buffer => { return emailHash } +const SecretKeyCryptographyEncrypt = (message: Buffer, encryptionKey: Buffer): Buffer => { + const encrypted = Buffer.alloc(sodium.crypto_secretbox_MACBYTES + message.length) + const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES) + nonce.fill(31) // static nonce + + sodium.crypto_secretbox_easy(encrypted, message, nonce, encryptionKey) + return encrypted +} + @Resolver() export class UserResolver { @Query(() => User) @@ -298,9 +304,10 @@ export class UserResolver { } const passphrase = PassphraseGenerate() - const keyPair = KeyPairEd25519Create(passphrase) - const passwordHash = SecretKeyCryptographyCreateKey(email, password) + const keyPair = KeyPairEd25519Create(passphrase) // return pub, priv Key + const passwordHash = SecretKeyCryptographyCreateKey(email, password) // return short and long hash const emailHash = getEmailHash(email) + const encryptedPrivkey = SecretKeyCryptographyEncrypt(keyPair[1], passwordHash[1]) // Table: login_users const loginUser = new LoginUser() @@ -315,7 +322,7 @@ export class UserResolver { loginUser.groupId = 1 loginUser.publisherId = publisherId loginUser.pubKey = keyPair[0] - loginUser.privKey = keyPair[1] + loginUser.privKey = encryptedPrivkey // TODO transaction const loginUserRepository = getCustomRepository(LoginUserRepository) @@ -328,7 +335,7 @@ export class UserResolver { // Table: login_user_backups const loginUserBackup = new LoginUserBackup() loginUserBackup.userId = loginUserId - loginUserBackup.passphrase = passphrase.join(' ') + loginUserBackup.passphrase = passphrase.join(' ') + ' ' // login server saves trailing space loginUserBackup.mnemonicType = 2 // ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; // TODO transaction From ab6418527575e54ce3e47e9cc0c73f56fa21bd3e Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Wed, 3 Nov 2021 21:36:47 +0100 Subject: [PATCH 29/47] test results --- backend/src/graphql/resolver/UserResolver.ts | 60 ++++++++++++-------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index dbe1aa6fa..7e0db4791 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -65,34 +65,48 @@ const PassphraseGenerate = (): string[] => { return result /* return [ - 'avoid', - 'security', - 'heavy', - 'mercy', - 'exit', - 'avocado', - 'actress', - 'apple', - 'crowd', - 'drop', - 'rib', - 'photo', - 'valley', - 'test', - 'board', - 'evidence', - 'blast', - 'pencil', + 'behind', + 'salmon', + 'fluid', + 'orphan', 'frost', - 'frame', - 'come', - 'vanish', - 'very', - 'inner', + 'elder', + 'amateur', + 'always', + 'panel', + 'palm', + 'leopard', + 'essay', + 'punch', + 'title', + 'fun', + 'annual', + 'page', + 'hundred', + 'journey', + 'select', + 'figure', + 'tunnel', + 'casual', + 'bar', ] */ } +/* +Test results: +INSERT INTO `login_users` (`id`, `email`, `first_name`, `last_name`, `username`, `description`, `password`, `pubkey`, `privkey`, `email_hash`, `created`, `email_checked`, `passphrase_shown`, `language`, `disabled`, `group_id`, `publisher_id`) VALUES +// old +(1, 'peter@lustig.de', 'peter', 'lustig', '', '', 4747956395458240931, 0x8c75edd507f470e5378f927489374694d68f3d155523f1c4402c36affd35a7ed, 0xb0e310655726b088631ccfd31ad6470ee50115c161dde8559572fa90657270ff13dc1200b2d3ea90dfbe92f3a4475ee4d9cee4989e39736a0870c33284bc73a8ae690e6da89f241a121eb3b500c22885, 0x9f700e6f6ec351a140b674c0edd4479509697b023bd8bee8826915ef6c2af036, '2021-11-03 20:05:04', 0, 0, 'de', 0, 1, 0); +// new +(2, 'peter@lustig.de', 'peter', 'lustig', '', '', 4747956395458240931, 0x8c75edd507f470e5378f927489374694d68f3d155523f1c4402c36affd35a7ed, 0xb0e310655726b088631ccfd31ad6470ee50115c161dde8559572fa90657270ff13dc1200b2d3ea90dfbe92f3a4475ee4d9cee4989e39736a0870c33284bc73a8ae690e6da89f241a121eb3b500c22885, 0x9f700e6f6ec351a140b674c0edd4479509697b023bd8bee8826915ef6c2af036, '2021-11-03 20:22:15', 0, 0, 'de', 0, 1, 0); +INSERT INTO `login_user_backups` (`id`, `user_id`, `passphrase`, `mnemonic_type`) VALUES +// old +(1, 1, 'behind salmon fluid orphan frost elder amateur always panel palm leopard essay punch title fun annual page hundred journey select figure tunnel casual bar ', 2); +// new +(2, 2, 'behind salmon fluid orphan frost elder amateur always panel palm leopard essay punch title fun annual page hundred journey select figure tunnel casual bar ', 2); +*/ + const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { if (!passphrase.length || passphrase.length < PHRASE_WORD_COUNT) { throw new Error('passphrase empty or to short') From 2bd63985b221e9ee0a03c9c6dd51f97828b35dc9 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Thu, 4 Nov 2021 02:18:19 +0100 Subject: [PATCH 30/47] externalize login server secrets, now configurable --- backend/.env.dist | 4 +++- backend/src/config/index.ts | 7 ++++++- backend/src/graphql/resolver/UserResolver.ts | 10 +++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/backend/.env.dist b/backend/.env.dist index 3ac50ac9b..98cf23263 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -18,4 +18,6 @@ DB_DATABASE=gradido_community COMMUNITY_NAME= COMMUNITY_URL= COMMUNITY_REGISTER_URL= -COMMUNITY_DESCRIPTION= \ No newline at end of file +COMMUNITY_DESCRIPTION= +LOGIN_APP_SECRET=21ffbbc616fe +LOGIN_SERVER_KEY=a51ef8ac7ef1abf162fb7a65261acd7a \ No newline at end of file diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 7de498f85..a5413b741 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -39,9 +39,14 @@ const community = { process.env.COMMUNITY_DESCRIPTION || 'Die lokale Entwicklungsumgebung von Gradido.', } +const loginServer = { + LOGIN_APP_SECRET: process.env.LOGIN_APP_SECRET || '21ffbbc616fe', + LOGIN_SERVER_KEY: process.env.LOGIN_SERVER_KEY || 'a51ef8ac7ef1abf162fb7a65261acd7a', +} + // This is needed by graphql-directive-auth process.env.APP_SECRET = server.JWT_SECRET -const CONFIG = { ...server, ...database, ...klicktipp, ...community } +const CONFIG = { ...server, ...database, ...klicktipp, ...community, ...loginServer } export default CONFIG diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 7e0db4791..1cabc49bd 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -142,9 +142,9 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { const SecretKeyCryptographyCreateKey = (salt: string, password: string): Buffer[] => { // TODO: put that in the actual config - const configCryptoAppSecret = Buffer.from('21ffbbc616fe', 'hex') - const configCryptoServerKey = Buffer.from('a51ef8ac7ef1abf162fb7a65261acd7a', 'hex') - if (configCryptoServerKey.length !== sodium.crypto_shorthash_KEYBYTES) { + const configLoginAppSecret = Buffer.from(CONFIG.LOGIN_APP_SECRET, 'hex') + const configLoginServerKey = Buffer.from(CONFIG.LOGIN_SERVER_KEY, 'hex') + if (configLoginServerKey.length !== sodium.crypto_shorthash_KEYBYTES) { throw new Error( `ServerKey has an invalid size. The size must be ${sodium.crypto_shorthash_KEYBYTES} bytes.`, ) @@ -153,7 +153,7 @@ const SecretKeyCryptographyCreateKey = (salt: string, password: string): Buffer[ const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES) sodium.crypto_hash_sha512_init(state) sodium.crypto_hash_sha512_update(state, Buffer.from(salt)) - sodium.crypto_hash_sha512_update(state, Buffer.from(configCryptoAppSecret)) + sodium.crypto_hash_sha512_update(state, configLoginAppSecret) const hash = Buffer.alloc(sodium.crypto_hash_sha512_BYTES) sodium.crypto_hash_sha512_final(state, hash) @@ -171,7 +171,7 @@ const SecretKeyCryptographyCreateKey = (salt: string, password: string): Buffer[ ) const encryptionKeyHash = Buffer.alloc(sodium.crypto_shorthash_BYTES) - sodium.crypto_shorthash(encryptionKeyHash, encryptionKey, configCryptoServerKey) + sodium.crypto_shorthash(encryptionKeyHash, encryptionKey, configLoginServerKey) return [encryptionKeyHash, encryptionKey] } From 1142f7359a4d0b60419efeb1a666c5fea0e175a9 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Nov 2021 10:50:47 +0100 Subject: [PATCH 31/47] Change the commit strategy so that the query runner store the commits and roll them back if their is an error. --- backend/src/graphql/resolver/UserResolver.ts | 100 +++++++++++-------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 1cabc49bd..8a3dfb6cd 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -3,7 +3,7 @@ import fs from 'fs' import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql' -import { getCustomRepository } from 'typeorm' +import { getConnection, getCustomRepository } from 'typeorm' import CONFIG from '../../config' import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode' import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse' @@ -324,7 +324,7 @@ export class UserResolver { const encryptedPrivkey = SecretKeyCryptographyEncrypt(keyPair[1], passwordHash[1]) // Table: login_users - const loginUser = new LoginUser() + let loginUser = new LoginUser() loginUser.email = email loginUser.firstName = firstName loginUser.lastName = lastName @@ -339,52 +339,66 @@ export class UserResolver { loginUser.privKey = encryptedPrivkey // TODO transaction - const loginUserRepository = getCustomRepository(LoginUserRepository) - const { id: loginUserId } = await loginUserRepository.save(loginUser).catch((error) => { - // eslint-disable-next-line no-console - console.log('insert user failed', error) - throw new Error('insert user failed') - }) + const queryRunner = getConnection().createQueryRunner() + // belong to debugging mysql query / typeorm line + // const startTime = new Date() + await queryRunner.connect() + await queryRunner.startTransaction('READ UNCOMMITTED') + try { + const { id: loginUserId } = await queryRunner.manager.save(loginUser).catch((error) => { + // eslint-disable-next-line no-console + console.log('insert LoginUser failed', error) + throw new Error('insert user failed') + }) - // Table: login_user_backups - const loginUserBackup = new LoginUserBackup() - loginUserBackup.userId = loginUserId - loginUserBackup.passphrase = passphrase.join(' ') + ' ' // login server saves trailing space - loginUserBackup.mnemonicType = 2 // ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; + // Table: login_user_backups + const loginUserBackup = new LoginUserBackup() + loginUserBackup.userId = loginUserId + loginUserBackup.passphrase = passphrase.join(' ') + ' ' // login server saves trailing space + loginUserBackup.mnemonicType = 2 // ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; - // TODO transaction - const loginUserBackupRepository = getCustomRepository(LoginUserBackupRepository) - await loginUserBackupRepository.save(loginUserBackup).catch(() => { - throw new Error('insert user backup failed') - }) + // TODO transaction + await queryRunner.manager.save(loginUserBackup).catch((error) => { + // eslint-disable-next-line no-console + console.log('insert LoginUserBackup failed', error) + throw new Error('insert user backup failed') + }) - // Table: state_users - const dbUser = new DbUser() - dbUser.pubkey = keyPair[0] - dbUser.email = email - dbUser.firstName = firstName - dbUser.lastName = lastName - dbUser.username = username + // Table: state_users + const dbUser = new DbUser() + dbUser.pubkey = keyPair[0] + dbUser.email = email + dbUser.firstName = firstName + dbUser.lastName = lastName + dbUser.username = username - // TDOO transaction - await userRepository.save(dbUser).catch((er) => { - // eslint-disable-next-line no-console - console.log('Error while saving dbUser', er) - throw new Error('error saving user') - }) + // TDOO transaction + await queryRunner.manager.save(dbUser).catch((er) => { + // eslint-disable-next-line no-console + console.log('Error while saving dbUser', er) + throw new Error('error saving user') + }) - // TODO: send EMail (EMAIL_OPT_IN_REGISTER) - // const emailType = 2 - // auto emailOptIn = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); - // auto emailOptInModel = emailOptIn->getModel(); - // if (!emailOptInModel->insertIntoDB(false)) { - // emailOptInModel->sendErrorsAsEmail(); - // return stateError("insert emailOptIn failed"); - // } - // emailOptIn->setBaseUrl(user->getGroupBaseUrl() + ServerConfig::g_frontend_checkEmailPath); - // em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); - - return 'success' + // TODO: send EMail (EMAIL_OPT_IN_REGISTER) + // const emailType = 2 + // auto emailOptIn = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); + // auto code = createEmailVerificationCode(); + // auto db = new model::table::EmailOptIn(code, userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); + // auto emailOptInModel = emailOptIn->getModel(); + // if (!emailOptInModel->insertIntoDB(false)) { + // emailOptInModel->sendErrorsAsEmail(); + // return stateError("insert emailOptIn failed"); + // } + // emailOptIn->setBaseUrl(user->getGroupBaseUrl() + ServerConfig::g_frontend_checkEmailPath); + // em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); + await queryRunner.commitTransaction() + return 'success' + } catch (e) { + await queryRunner.rollbackTransaction() + throw e + } finally { + await queryRunner.release() + } } @Query(() => SendPasswordResetEmailResponse) From dcdcb1c977c02a5c34e386083a82ab73f8053e81 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Nov 2021 12:17:30 +0100 Subject: [PATCH 32/47] Added rollback of auto increment index for state_users, login_users & login_user_backups --- backend/src/graphql/resolver/UserResolver.ts | 28 +++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 8a3dfb6cd..fc57e793d 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -3,7 +3,7 @@ import fs from 'fs' import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql' -import { getConnection, getCustomRepository } from 'typeorm' +import { BaseEntity, getConnection, getCustomRepository, QueryRunner } from 'typeorm' import CONFIG from '../../config' import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode' import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse' @@ -324,7 +324,7 @@ export class UserResolver { const encryptedPrivkey = SecretKeyCryptographyEncrypt(keyPair[1], passwordHash[1]) // Table: login_users - let loginUser = new LoginUser() + const loginUser = new LoginUser() loginUser.email = email loginUser.firstName = firstName loginUser.lastName = lastName @@ -338,10 +338,7 @@ export class UserResolver { loginUser.pubKey = keyPair[0] loginUser.privKey = encryptedPrivkey - // TODO transaction const queryRunner = getConnection().createQueryRunner() - // belong to debugging mysql query / typeorm line - // const startTime = new Date() await queryRunner.connect() await queryRunner.startTransaction('READ UNCOMMITTED') try { @@ -357,7 +354,6 @@ export class UserResolver { loginUserBackup.passphrase = passphrase.join(' ') + ' ' // login server saves trailing space loginUserBackup.mnemonicType = 2 // ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER; - // TODO transaction await queryRunner.manager.save(loginUserBackup).catch((error) => { // eslint-disable-next-line no-console console.log('insert LoginUserBackup failed', error) @@ -372,7 +368,6 @@ export class UserResolver { dbUser.lastName = lastName dbUser.username = username - // TDOO transaction await queryRunner.manager.save(dbUser).catch((er) => { // eslint-disable-next-line no-console console.log('Error while saving dbUser', er) @@ -395,6 +390,9 @@ export class UserResolver { return 'success' } catch (e) { await queryRunner.rollbackTransaction() + await rollbackAutoIncrement(queryRunner, LoginUser, `login_users`) + await rollbackAutoIncrement(queryRunner, LoginUserBackup, `login_user_backups`) + await rollbackAutoIncrement(queryRunner, DbUser, `state_users`) throw e } finally { await queryRunner.release() @@ -569,3 +567,19 @@ export class UserResolver { return result.data.hasElopage } } + +const rollbackAutoIncrement = async ( + queryRunner: QueryRunner, + entity: typeof BaseEntity, + entityName: string, +) => { + const count = await queryRunner.manager.count(entity) + const queryString = 'ALTER TABLE `' + entityName + '` auto_increment = ' + count + // eslint-disable-next-line no-console + console.log('Database AlterTable Query: ', queryString) + await queryRunner.query(queryString).catch((error) => { + // eslint-disable-next-line no-console + console.log('problems with reset auto increment: %o', error) + throw new Error('Problems with reset auto increment: ' + error) + }) +} From 137d68335187dbf319db42c3a38a3831c62985da Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Nov 2021 12:20:09 +0100 Subject: [PATCH 33/47] Update and adding some packages.updated: typeorm, imported: sodium-native, node-gyp-build & module-alias. --- backend/package-lock.json | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 448700c9f..b998613b5 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,6 +1,6 @@ { "name": "gradido-backend", - "version": "1.4.0", + "version": "1.5.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -5069,6 +5069,11 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, + "module-alias": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", + "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5156,6 +5161,11 @@ "whatwg-url": "^5.0.0" } }, + "node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6109,6 +6119,14 @@ "is-fullwidth-code-point": "^3.0.0" } }, + "sodium-native": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.3.0.tgz", + "integrity": "sha512-rg6lCDM/qa3p07YGqaVD+ciAbUqm6SoO4xmlcfkbU5r1zIGrguXztLiEtaLYTV5U6k8KSIUFmnU3yQUSKmf6DA==", + "requires": { + "node-gyp-build": "^4.3.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6603,9 +6621,9 @@ } }, "typeorm": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.37.tgz", - "integrity": "sha512-7rkW0yCgFC24I5T0f3S/twmLSuccPh1SQmxET/oDWn2sSDVzbyWdnItSdKy27CdJGTlKHYtUVeOcMYw5LRsXVw==", + "version": "0.2.38", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.38.tgz", + "integrity": "sha512-M6Y3KQcAREQcphOVJciywf4mv6+A0I/SeR+lWNjKsjnQ+a3XcMwGYMGL0Jonsx3H0Cqlf/3yYqVki1jIXSK/xg==", "requires": { "@sqltools/formatter": "^1.2.2", "app-root-path": "^3.0.0", From d097e5cd76f065eabae8abb0ccdb200545c5cddd Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Nov 2021 12:55:04 +0100 Subject: [PATCH 34/47] Created the LoginEmailOptIn table entity. --- .../LoginEmailOptIn.ts | 26 +++++++++++++++++++ database/entity/LoginEmailOptIn.ts | 1 + 2 files changed, 27 insertions(+) create mode 100644 database/entity/0003-login_server_tables/LoginEmailOptIn.ts create mode 100644 database/entity/LoginEmailOptIn.ts diff --git a/database/entity/0003-login_server_tables/LoginEmailOptIn.ts b/database/entity/0003-login_server_tables/LoginEmailOptIn.ts new file mode 100644 index 000000000..e07411dfb --- /dev/null +++ b/database/entity/0003-login_server_tables/LoginEmailOptIn.ts @@ -0,0 +1,26 @@ +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm' + +// Moriz: I do not like the idea of having two user tables +@Entity('login_email_opt_in') +export class LoginEmailOptIn extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column() + userId: number + + @Column({ name: 'verification_code', type: 'bigint', unsigned: true }) + verificationCode: BigInt + + @Column({ name: 'email_opt_in_type_id' }) + emailOptInTypeId: number + + @Column({ name: 'created', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date + + @Column({ name: 'resend_count', default: 0 }) + resendCount: number + + @Column({ name: 'updated', default: () => 'CURRENT_TIMESTAMP' }) + updatedAt: Date +} diff --git a/database/entity/LoginEmailOptIn.ts b/database/entity/LoginEmailOptIn.ts new file mode 100644 index 000000000..fa8717ed3 --- /dev/null +++ b/database/entity/LoginEmailOptIn.ts @@ -0,0 +1 @@ +export { LoginEmailOptIn } from './0003-login_server_tables/LoginEmailOptIn' From 8bfc5388246f57ef0ac1fe5e13faef2691d1bb8f Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Nov 2021 12:57:28 +0100 Subject: [PATCH 35/47] Added random-bigint library for verificationCode, store EmailOptIn data in DB. --- backend/package-lock.json | 5 ++++ backend/package.json | 1 + backend/src/graphql/resolver/UserResolver.ts | 30 +++++++++++++------- backend/yarn.lock | 5 ++++ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index b998613b5..a174865aa 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -5697,6 +5697,11 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "random-bigint": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/random-bigint/-/random-bigint-0.0.1.tgz", + "integrity": "sha512-X+NTsf5Hzl/tRNLiNTD3N1LRU0eKdIE0+plNlV1CmXLTlnAxj6HipcTnOhWvFRoSytCz6l1f4KYFf/iH8NNSLw==" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", diff --git a/backend/package.json b/backend/package.json index ee7365b72..9da51cb7f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -28,6 +28,7 @@ "jsonwebtoken": "^8.5.1", "module-alias": "^2.2.2", "mysql2": "^2.3.0", + "random-bigint": "^0.0.1", "reflect-metadata": "^0.1.13", "sodium-native": "^3.3.0", "ts-jest": "^27.0.5", diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index fc57e793d..6c140bc62 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -29,6 +29,7 @@ import { LoginUserRepository } from '../../typeorm/repository/LoginUser' import { LoginUserBackupRepository } from '../../typeorm/repository/LoginUserBackup' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' +import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' // TODO apparently the types are cannot be loaded correctly? IDK whats wrong and we have to use require // import { @@ -43,6 +44,8 @@ import { LoginUserBackup } from '@entity/LoginUserBackup' // } from 'sodium-native' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') +// eslint-disable-next-line @typescript-eslint/no-var-requires +const random = require('random-bigint') // We will reuse this for changePassword const isPassword = (password: string): boolean => { @@ -374,16 +377,23 @@ export class UserResolver { throw new Error('error saving user') }) - // TODO: send EMail (EMAIL_OPT_IN_REGISTER) - // const emailType = 2 - // auto emailOptIn = controller::EmailVerificationCode::create(userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); - // auto code = createEmailVerificationCode(); - // auto db = new model::table::EmailOptIn(code, userModel->getID(), model::table::EMAIL_OPT_IN_REGISTER); - // auto emailOptInModel = emailOptIn->getModel(); - // if (!emailOptInModel->insertIntoDB(false)) { - // emailOptInModel->sendErrorsAsEmail(); - // return stateError("insert emailOptIn failed"); - // } + // Store EmailOptIn in DB + const emailOptIn = new LoginEmailOptIn() + emailOptIn.userId = loginUserId + emailOptIn.verificationCode = random(64) // TODO generate verificationCode + emailOptIn.emailOptInTypeId = 2 + + await queryRunner.manager.save(emailOptIn).catch((error) => { + // TODO: Send error email instead of throw error + // if (!emailOptInModel->insertIntoDB(false)) { + // emailOptInModel->sendErrorsAsEmail(); + // return stateError("insert emailOptIn failed"); + // } + // eslint-disable-next-line no-console + console.log('Error while saving emailOptIn', error) + throw new Error('error saving email opt in') + }) + // TODO: Send EmailOptIn to user.email // emailOptIn->setBaseUrl(user->getGroupBaseUrl() + ServerConfig::g_frontend_checkEmailPath); // em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); await queryRunner.commitTransaction() diff --git a/backend/yarn.lock b/backend/yarn.lock index 7cd146647..75b998c17 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -4615,6 +4615,11 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +random-bigint@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/random-bigint/-/random-bigint-0.0.1.tgz#684de0a93784ab7448a441393916f0e632c95df9" + integrity sha512-X+NTsf5Hzl/tRNLiNTD3N1LRU0eKdIE0+plNlV1CmXLTlnAxj6HipcTnOhWvFRoSytCz6l1f4KYFf/iH8NNSLw== + range-parser@~1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" From c7f0e2440bdf44db6d1dce0d06ce3b0e8c395dbf Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Nov 2021 13:50:09 +0100 Subject: [PATCH 36/47] Change so that the new entity is recognized by the queryRunner. --- backend/src/typeorm/repository/LoginEmailOptIn.ts | 5 +++++ database/entity/0003-login_server_tables/LoginEmailOptIn.ts | 4 ++-- database/entity/index.ts | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 backend/src/typeorm/repository/LoginEmailOptIn.ts diff --git a/backend/src/typeorm/repository/LoginEmailOptIn.ts b/backend/src/typeorm/repository/LoginEmailOptIn.ts new file mode 100644 index 000000000..cb486d922 --- /dev/null +++ b/backend/src/typeorm/repository/LoginEmailOptIn.ts @@ -0,0 +1,5 @@ +import { EntityRepository, Repository } from 'typeorm' +import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' + +@EntityRepository(LoginEmailOptIn) +export class LoginEmailOptInRepository extends Repository {} diff --git a/database/entity/0003-login_server_tables/LoginEmailOptIn.ts b/database/entity/0003-login_server_tables/LoginEmailOptIn.ts index e07411dfb..2ec62927f 100644 --- a/database/entity/0003-login_server_tables/LoginEmailOptIn.ts +++ b/database/entity/0003-login_server_tables/LoginEmailOptIn.ts @@ -6,10 +6,10 @@ export class LoginEmailOptIn extends BaseEntity { @PrimaryGeneratedColumn('increment', { unsigned: true }) id: number - @Column() + @Column({ name: 'user_id' }) userId: number - @Column({ name: 'verification_code', type: 'bigint', unsigned: true }) + @Column({ name: 'verification_code', type: 'bigint', unsigned: true, unique: true }) verificationCode: BigInt @Column({ name: 'email_opt_in_type_id' }) diff --git a/database/entity/index.ts b/database/entity/index.ts index da6761da2..ff1d34d9e 100644 --- a/database/entity/index.ts +++ b/database/entity/index.ts @@ -1,4 +1,5 @@ import { Balance } from './Balance' +import { LoginEmailOptIn } from './LoginEmailOptIn' import { LoginUser } from './LoginUser' import { LoginUserBackup } from './LoginUserBackup' import { Migration } from './Migration' @@ -13,6 +14,7 @@ export const entities = [ Balance, LoginUser, LoginUserBackup, + LoginEmailOptIn, Migration, Transaction, TransactionCreation, From d15b9a7e3ce7c529cfd0dd6e3c292dbfce41f0b5 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Thu, 4 Nov 2021 18:04:06 +0100 Subject: [PATCH 37/47] - do not send error email - return after finally block due to unknown behaviour?! --- backend/src/graphql/resolver/UserResolver.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 6c140bc62..ae8d0f8b1 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -384,11 +384,6 @@ export class UserResolver { emailOptIn.emailOptInTypeId = 2 await queryRunner.manager.save(emailOptIn).catch((error) => { - // TODO: Send error email instead of throw error - // if (!emailOptInModel->insertIntoDB(false)) { - // emailOptInModel->sendErrorsAsEmail(); - // return stateError("insert emailOptIn failed"); - // } // eslint-disable-next-line no-console console.log('Error while saving emailOptIn', error) throw new Error('error saving email opt in') @@ -397,7 +392,6 @@ export class UserResolver { // emailOptIn->setBaseUrl(user->getGroupBaseUrl() + ServerConfig::g_frontend_checkEmailPath); // em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); await queryRunner.commitTransaction() - return 'success' } catch (e) { await queryRunner.rollbackTransaction() await rollbackAutoIncrement(queryRunner, LoginUser, `login_users`) @@ -407,6 +401,7 @@ export class UserResolver { } finally { await queryRunner.release() } + return 'success' } @Query(() => SendPasswordResetEmailResponse) From 854ce12d620ea125d696b27daf248995a55f060d Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Thu, 4 Nov 2021 18:08:59 +0100 Subject: [PATCH 38/47] removed dangerous code --- backend/src/graphql/resolver/UserResolver.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index ae8d0f8b1..55cf5b81f 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -394,9 +394,11 @@ export class UserResolver { await queryRunner.commitTransaction() } catch (e) { await queryRunner.rollbackTransaction() - await rollbackAutoIncrement(queryRunner, LoginUser, `login_users`) - await rollbackAutoIncrement(queryRunner, LoginUserBackup, `login_user_backups`) - await rollbackAutoIncrement(queryRunner, DbUser, `state_users`) + // TODO: Lets not do this?! What if state_users were never updated? + // We would still roll back the autoincrement which would produce duplicate entries?! + // await rollbackAutoIncrement(queryRunner, LoginUser, `login_users`) + // await rollbackAutoIncrement(queryRunner, LoginUserBackup, `login_user_backups`) + // await rollbackAutoIncrement(queryRunner, DbUser, `state_users`) throw e } finally { await queryRunner.release() @@ -573,6 +575,7 @@ export class UserResolver { } } +/* const rollbackAutoIncrement = async ( queryRunner: QueryRunner, entity: typeof BaseEntity, @@ -588,3 +591,4 @@ const rollbackAutoIncrement = async ( throw new Error('Problems with reset auto increment: ' + error) }) } +*/ From f915bd40131cdd5a355f1a04847b39d9ba03718e Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 00:45:36 +0100 Subject: [PATCH 39/47] removed unused includes --- backend/src/graphql/resolver/UserResolver.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 55cf5b81f..c3c8e0f14 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -3,7 +3,7 @@ import fs from 'fs' import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql' -import { BaseEntity, getConnection, getCustomRepository, QueryRunner } from 'typeorm' +import { getConnection, getCustomRepository } from 'typeorm' import CONFIG from '../../config' import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode' import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse' @@ -25,8 +25,6 @@ import { CheckEmailResponse } from '../model/CheckEmailResponse' import { UserSettingRepository } from '../../typeorm/repository/UserSettingRepository' import { Setting } from '../enum/Setting' import { UserRepository } from '../../typeorm/repository/User' -import { LoginUserRepository } from '../../typeorm/repository/LoginUser' -import { LoginUserBackupRepository } from '../../typeorm/repository/LoginUserBackup' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' From 95265fe9898bcf59f5da4c4b96598110ef9414e7 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 00:55:27 +0100 Subject: [PATCH 40/47] removed @types/libsodium-wrapper package --- backend/package.json | 1 - backend/yarn.lock | 5 ----- 2 files changed, 6 deletions(-) diff --git a/backend/package.json b/backend/package.json index e47939b41..bc098958f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -40,7 +40,6 @@ "devDependencies": { "@types/express": "^4.17.12", "@types/jsonwebtoken": "^8.5.2", - "@types/libsodium-wrappers": "^0.7.9", "@types/node": "^16.10.3", "@types/nodemailer": "^6.4.4", "@typescript-eslint/eslint-plugin": "^4.28.0", diff --git a/backend/yarn.lock b/backend/yarn.lock index 915766619..b411bcf60 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -918,11 +918,6 @@ "@types/koa-compose" "*" "@types/node" "*" -"@types/libsodium-wrappers@^0.7.9": - version "0.7.9" - resolved "https://registry.yarnpkg.com/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz#89c3ad2156d5143e64bce86cfeb0045a983aeccc" - integrity sha512-LisgKLlYQk19baQwjkBZZXdJL0KbeTpdEnrAfz5hQACbklCY0gVFnsKUyjfNWF1UQsCSjw93Sj5jSbiO8RPfdw== - "@types/long@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" From 4e118b65ee8389bca6083f19c2109d3eea414c1f Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 00:57:05 +0100 Subject: [PATCH 41/47] - make sendEMails external (utils) - replace fromHex from libsodium-wrapper --- .../graphql/resolver/TransactionResolver.ts | 28 ++----------------- backend/src/util/sendEMail.ts | 26 +++++++++++++++++ 2 files changed, 28 insertions(+), 26 deletions(-) create mode 100644 backend/src/util/sendEMail.ts diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 70dfdc505..afdd87156 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -4,9 +4,9 @@ import { Resolver, Query, Args, Authorized, Ctx, Mutation } from 'type-graphql' import { getCustomRepository, getConnection, QueryRunner } from 'typeorm' -import { createTransport } from 'nodemailer' import CONFIG from '../../config' +import { sendEMail } from '../../util/sendEMail' import { Transaction } from '../model/Transaction' import { TransactionList } from '../model/TransactionList' @@ -33,7 +33,6 @@ import { calculateDecay, calculateDecayWithInterval } from '../../util/decay' import { TransactionTypeId } from '../enum/TransactionTypeId' import { TransactionType } from '../enum/TransactionType' import { hasUserAmount, isHexPublicKey } from '../../util/validate' -import { from_hex as fromHex } from 'libsodium-wrappers' /* # Test @@ -201,29 +200,6 @@ INSERT INTO `transaction_signatures` (`id`, `transaction_id`, `signature`, `pubk (1, 1, 0x60d632479707e5d01cdc32c3326b5a5bae11173a0c06b719ee7b552f9fd644de1a0cd4afc207253329081d39dac1a63421f51571d836995c649fc39afac7480a, 0x48c45cb4fea925e83850f68f2fa8f27a1a4ed1bcba68cdb59fcd86adef3f52ee); */ -const sendEMail = async (emailDef: any): Promise => { - if (!CONFIG.EMAIL) { - // eslint-disable-next-line no-console - console.log('Emails are disabled via config') - return false - } - const transporter = createTransport({ - host: CONFIG.EMAIL_SMTP_URL, - port: Number(CONFIG.EMAIL_SMTP_PORT), - secure: false, // true for 465, false for other ports - requireTLS: true, - auth: { - user: CONFIG.EMAIL_USERNAME, - pass: CONFIG.EMAIL_PASSWORD, - }, - }) - const info = await transporter.sendMail(emailDef) - if (!info.messageId) { - throw new Error('error sending notification email, but transaction succeed') - } - return true -} - // Helper function async function calculateAndAddDecayTransactions( userTransactions: dbUserTransaction[], @@ -622,7 +598,7 @@ export class TransactionResolver { transactionSendCoin.userId = senderUser.id transactionSendCoin.senderPublic = senderUser.pubkey transactionSendCoin.recipiantUserId = recipiantUser.id - transactionSendCoin.recipiantPublic = Buffer.from(fromHex(recipiantPublicKey)) + transactionSendCoin.recipiantPublic = Buffer.from(recipiantPublicKey, 'hex') transactionSendCoin.amount = centAmount transactionSendCoin.senderFinalBalance = senderStateBalance.amount await queryRunner.manager.save(transactionSendCoin).catch((error) => { diff --git a/backend/src/util/sendEMail.ts b/backend/src/util/sendEMail.ts new file mode 100644 index 000000000..e34597419 --- /dev/null +++ b/backend/src/util/sendEMail.ts @@ -0,0 +1,26 @@ +import { createTransport } from 'nodemailer' + +import CONFIG from '../config' + +export const sendEMail = async (emailDef: any): Promise => { + if (!CONFIG.EMAIL) { + // eslint-disable-next-line no-console + console.log('Emails are disabled via config') + return false + } + const transporter = createTransport({ + host: CONFIG.EMAIL_SMTP_URL, + port: Number(CONFIG.EMAIL_SMTP_PORT), + secure: false, // true for 465, false for other ports + requireTLS: true, + auth: { + user: CONFIG.EMAIL_USERNAME, + pass: CONFIG.EMAIL_PASSWORD, + }, + }) + const info = await transporter.sendMail(emailDef) + if (!info.messageId) { + throw new Error('error sending notification email, but transaction succeed') + } + return true +} From 9894b4a91ffd1d064029aa735ff70533b0f3b09e Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 01:56:30 +0100 Subject: [PATCH 42/47] fixed email for transactions --- backend/src/graphql/resolver/TransactionResolver.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index afdd87156..755955a7f 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -630,8 +630,8 @@ export class TransactionResolver { // send notification email // TODO: translate await sendEMail({ - from: 'Gradido (nicht antworten) <' + CONFIG.EMAIL_SENDER + '>', - to: recipiantUser.firstName + ' ' + recipiantUser.lastName + ' <' + recipiantUser.email + '>', + from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, + to: `${recipiantUser.firstName} ${recipiantUser.lastName} <${recipiantUser.email}>`, subject: 'Gradido Überweisung', text: `Hallo ${recipiantUser.firstName} ${recipiantUser.lastName} @@ -642,7 +642,8 @@ export class TransactionResolver { Bitte antworte nicht auf diese E-Mail! - Mit freundlichen Grüßen Gradido Community Server`, + Mit freundlichen Grüßen, + dein Gradido-Team`, }) return 'success' From 0f89cf1c9688fe4caa51cec12b78a3628332942a Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 01:56:47 +0100 Subject: [PATCH 43/47] send emails to activate account --- backend/.env.dist | 2 ++ backend/src/config/index.ts | 3 ++ backend/src/graphql/resolver/UserResolver.ts | 33 +++++++++++++++++--- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/backend/.env.dist b/backend/.env.dist index 30c0da2db..b4a91026a 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -18,6 +18,8 @@ DB_DATABASE=gradido_community #EMAIL_SMTP_URL= #EMAIL_SMTP_PORT=587 +#EMAIL_LINK_VERIFICATION=http://localhost/vue/checkEmail/$1 + #KLICKTIPP_USER= #KLICKTIPP_PASSWORD= #KLICKTIPP_APIKEY_DE= diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 7e2059eac..f21082d1d 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -51,6 +51,9 @@ const email = { EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || 'xxx', EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com', EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587', + + EMAIL_LINK_VERIFICATION: + process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/vue/checkEmail/$1', } // This is needed by graphql-directive-auth diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index c3c8e0f14..6a8eed67f 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -28,6 +28,7 @@ import { UserRepository } from '../../typeorm/repository/User' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' +import { sendEMail } from '../../util/sendEMail' // TODO apparently the types are cannot be loaded correctly? IDK whats wrong and we have to use require // import { @@ -378,7 +379,7 @@ export class UserResolver { // Store EmailOptIn in DB const emailOptIn = new LoginEmailOptIn() emailOptIn.userId = loginUserId - emailOptIn.verificationCode = random(64) // TODO generate verificationCode + emailOptIn.verificationCode = random(64) emailOptIn.emailOptInTypeId = 2 await queryRunner.manager.save(emailOptIn).catch((error) => { @@ -386,9 +387,33 @@ export class UserResolver { console.log('Error while saving emailOptIn', error) throw new Error('error saving email opt in') }) - // TODO: Send EmailOptIn to user.email - // emailOptIn->setBaseUrl(user->getGroupBaseUrl() + ServerConfig::g_frontend_checkEmailPath); - // em->addEmail(new model::Email(emailOptIn, user, model::Email::convertTypeFromInt(emailType))); + + // Send EMail to user + const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace( + /\$1/g, + emailOptIn.verificationCode.toString(), + ) + const emailSent = await sendEMail({ + from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, + to: `${firstName} ${lastName} <${email}>`, + subject: 'Gradido: E-Mail Überprüfung', + text: `Hallo ${firstName} ${lastName}, + + Deine EMail wurde soeben bei Gradido registriert. + + Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren: + ${activationLink} + oder kopiere den obigen Link in dein Browserfenster. + + Mit freundlichen Grüßen, + dein Gradido-Team`, + }) + + // In case EMails are disabled log the activation link for the user + if (!emailSent) { + // eslint-disable-next-line no-console + console.log(`Account confirmation link: ${activationLink}`) + } await queryRunner.commitTransaction() } catch (e) { await queryRunner.rollbackTransaction() From fe9a8e1a7501ce18aa3b2a64a2920d25b40ed96b Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 02:05:21 +0100 Subject: [PATCH 44/47] reduced coverage to 39 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 08e63e6bb..9b10b7250 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -394,7 +394,7 @@ jobs: report_name: Coverage Backend type: lcov result_path: ./backend/coverage/lcov.info - min_coverage: 41 + min_coverage: 39 token: ${{ github.token }} ############################################################################## From 70fa4f49d0a7832ddf6e70f3367fa8689e81f116 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 02:10:35 +0100 Subject: [PATCH 45/47] cleanup --- backend/src/graphql/resolver/UserResolver.ts | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 6a8eed67f..f332a56bf 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -30,17 +30,6 @@ import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { sendEMail } from '../../util/sendEMail' -// TODO apparently the types are cannot be loaded correctly? IDK whats wrong and we have to use require -// import { -// /* eslint-disable camelcase */ -// randombytes_random, -// crypto_hash_sha512_instance, -// crypto_hash_sha512_BYTES, -// crypto_sign_seed_keypair, -// crypto_sign_PUBLICKEYBYTES, -// crypto_sign_SECRETKEYBYTES, -// /* eslint-enable camelcase */ -// } from 'sodium-native' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -143,7 +132,6 @@ const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => { } const SecretKeyCryptographyCreateKey = (salt: string, password: string): Buffer[] => { - // TODO: put that in the actual config const configLoginAppSecret = Buffer.from(CONFIG.LOGIN_APP_SECRET, 'hex') const configLoginServerKey = Buffer.from(CONFIG.LOGIN_SERVER_KEY, 'hex') if (configLoginServerKey.length !== sodium.crypto_shorthash_KEYBYTES) { @@ -287,8 +275,6 @@ export class UserResolver { async createUser( @Args() { email, firstName, lastName, password, language, publisherId }: CreateUserArgs, ): Promise { - const username = '' - // TODO: wrong default value (should be null), how does graphql work here? Is it an required field? // default int publisher_id = 0; @@ -306,6 +292,7 @@ export class UserResolver { // Validate username // TODO: never true + const username = '' if (username.length > 3 && !this.checkUsername({ username })) { throw new Error('Username already in use') } From d73728bf8695d4bb42b3791764be9ef07f8b272c Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 18:55:04 +0100 Subject: [PATCH 46/47] Update backend/src/graphql/resolver/UserResolver.ts Co-authored-by: Hannes Heine --- backend/src/graphql/resolver/UserResolver.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f332a56bf..c0ec4b932 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -584,21 +584,3 @@ export class UserResolver { return result.data.hasElopage } } - -/* -const rollbackAutoIncrement = async ( - queryRunner: QueryRunner, - entity: typeof BaseEntity, - entityName: string, -) => { - const count = await queryRunner.manager.count(entity) - const queryString = 'ALTER TABLE `' + entityName + '` auto_increment = ' + count - // eslint-disable-next-line no-console - console.log('Database AlterTable Query: ', queryString) - await queryRunner.query(queryString).catch((error) => { - // eslint-disable-next-line no-console - console.log('problems with reset auto increment: %o', error) - throw new Error('Problems with reset auto increment: ' + error) - }) -} -*/ From 348075ab386b858cd8a3634f95bc067d464279e5 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Sat, 6 Nov 2021 18:55:16 +0100 Subject: [PATCH 47/47] Update backend/src/graphql/resolver/UserResolver.ts Co-authored-by: Hannes Heine --- backend/src/graphql/resolver/UserResolver.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index c0ec4b932..7cc8cbf6d 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -404,11 +404,6 @@ export class UserResolver { await queryRunner.commitTransaction() } catch (e) { await queryRunner.rollbackTransaction() - // TODO: Lets not do this?! What if state_users were never updated? - // We would still roll back the autoincrement which would produce duplicate entries?! - // await rollbackAutoIncrement(queryRunner, LoginUser, `login_users`) - // await rollbackAutoIncrement(queryRunner, LoginUserBackup, `login_user_backups`) - // await rollbackAutoIncrement(queryRunner, DbUser, `state_users`) throw e } finally { await queryRunner.release()