mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-12 23:35:50 +00:00
86 lines
2.9 KiB
Plaintext
86 lines
2.9 KiB
Plaintext
/* MIGRATION TO CLEAN PRODUCTION DATA
|
|
*
|
|
* the way the passphrases are stored in login_user_backups is inconsistent.
|
|
* we need to try to detect which word list was used and transform it accordingly
|
|
*/
|
|
|
|
import fs from 'fs'
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
const sodium = require('sodium-native')
|
|
|
|
const PHRASE_WORD_COUNT = 24
|
|
const WORDS = fs
|
|
.readFileSync('src/config/mnemonic.uncompressed_buffer13116.txt')
|
|
.toString()
|
|
.split(',')
|
|
|
|
const KeyPairEd25519Create = (passphrase: string[]): Buffer[] => {
|
|
if (!passphrase.length || passphrase.length < PHRASE_WORD_COUNT) {
|
|
throw new Error('passphrase empty or to short')
|
|
}
|
|
|
|
const state = Buffer.alloc(sodium.crypto_hash_sha512_STATEBYTES)
|
|
sodium.crypto_hash_sha512_init(state)
|
|
|
|
for (let i = 0; i < PHRASE_WORD_COUNT; i++) {
|
|
const value = Buffer.alloc(8)
|
|
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
|
|
const clearPassphrase = passphrase.slice(0, PHRASE_WORD_COUNT).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)
|
|
|
|
const pubKey = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES)
|
|
const privKey = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES)
|
|
|
|
sodium.crypto_sign_seed_keypair(
|
|
pubKey,
|
|
privKey,
|
|
outputHashBuffer.slice(0, sodium.crypto_sign_SEEDBYTES),
|
|
)
|
|
|
|
return [pubKey, privKey]
|
|
}
|
|
|
|
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
|
// Delete data with no reference in login_users table
|
|
// eslint-disable-next-line no-console
|
|
// 663 affected rows
|
|
const userBackups = await queryFn(
|
|
`SELECT passphrase, LOWER(HEX(pubkey)) as pubkey, user_id
|
|
FROM login_user_backups
|
|
LEFT JOIN login_users ON login_user_backups.user_id = login_users.id
|
|
WHERE user_id=1503`,
|
|
// WHERE pubkey is not null`, // todo fix this condition and regenerate
|
|
)
|
|
let i = 0
|
|
// eslint-disable-next-line no-console
|
|
userBackups.forEach(async (userBackup) => {
|
|
const passphrase = userBackup.passphrase.split(' ')
|
|
const keyPair = KeyPairEd25519Create(passphrase)
|
|
if (keyPair[0].toString('hex') !== userBackup.pubkey) {
|
|
i++
|
|
// eslint-disable-next-line no-console
|
|
console.log(
|
|
'Missmatch Pubkey',
|
|
i,
|
|
userBackup.user_id,
|
|
`"${userBackup.passphrase}"`,
|
|
`"${keyPair[0].toString('hex')}`,
|
|
`"${userBackup.pubkey}"`,
|
|
)
|
|
} else {
|
|
// eslint-disable-next-line no-console
|
|
// console.log('SUCCESS: ', `"${keyPair[0].toString('hex')}`, `"${userBackup.pubkey}"`)
|
|
}
|
|
})
|
|
}
|
|
|
|
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
|
return [] // cannot transform things back
|
|
} |