<commit_before>import API from "@js/Helper/api";
import Utility from '@js/Classes/Utility';
import Messages from '@js/Classes/Messages';
import Application from '@js/Init/Application';
import Localisation from '@js/Classes/Localisation';
import EventManager from '@js/Manager/EventManager';
import SettingsService from "@js/Services/SettingsService";

class EncryptionManager {

    constructor() {
        this._statusFunc = null;
        this.status = null;
    }

    /**
     *
     * @param password
     * @param save
     * @param encrypt
     * @param statusFunc
     */
    async install(password, save = false, encrypt = false, statusFunc = null) {
        this._resetStatus(statusFunc);
        await this._updateKeychain(password);

        if(encrypt !== false) {
            let tagMap    = {},
                folderMap = {};

            await Promise.all(
                [
                    this._encryptTags(tagMap),
                    this._encryptFolders(folderMap)
                ]
            );

            await this._encryptPasswords(folderMap, tagMap);
            await this._cleanDatabase(tagMap, folderMap);
        }

        if(save) await this._saveMasterPassword(password);
        Application.loginRequired = true;
    }

    /**
     *
     * @param password
     * @param oldPassword
     * @returns {Promise<void>}
     */
    async update(password, oldPassword) {
        try {
            await API.setAccountChallenge(password, oldPassword);
        } catch(e) {
            throw e;
        }
    }

    /**
     *
     * @returns {Promise<void>}
     */
    async updateGui() {
        let data = await Messages.form(
            {
                password      : {
                    label    : 'New password',
                    type     : 'password',
                    button   : 'toggle',
                    minlength: 12,
                    required : true,
                    title    : 'Your password must be longer than 12 characters and not the old password',
                    validator: (value, fields) => {
                        return value !== fields.oldPassword && value.length >= 12;
                    }
                },
                repeatPassword: {
                    label    : 'Repeat password',
                    type     : 'password',
                    button   : 'toggle',
                    required : true,
                    title    : 'Please confirm your new password',
                    validator: (value, fields) => {
                        return value === fields.password;
                    }
                },
                oldPassword   : {
                    label    : 'Old password',
                    type     : 'password',
                    button   : 'toggle',
                    title    : 'You must enter your old password',
                    required : true,
                    validator: (value) => {
                        return value.length >= 12;
                    }
                }
            },
            'Change Password',
            'You can use this dialog to change your master password.'
        );

        try {
            this._lockApp();
            await this.update(data.password, data.oldPassword);
            this._unlockApp();

            Messages.alert('Your password has been changed successfully.', 'Password changed');
        } catch(e) {
            this._unlockApp();
            Messages.alert(e.message, 'Changing password failed');
            console.error(e);
        }
    }

    /**
     *
     * @param password
     * @returns {Promise<void>}
     * @private
     */
    async _updateKeychain(password) {
        this._sendStatus('keychain', 'processing', 1);
        try {
            await API.setAccountChallenge(password);
            await Promise.all([await SettingsService.reset('user.encryption.cse'), await SettingsService.reset('user.encryption.sse')]);
            this._sendStatus('keychain', 'done');
        } catch(e) {
            this._sendStatus('keychain', 'error', e);
            throw e;
        }
    }

    /**
     *
     * @param folderMap
     * @param tagMap
     * @returns {Promise<void>}
     * @private
     */
    async _encryptPasswords(folderMap, tagMap) {
        this._sendStatus('passwords', 'loading');
        let passwords = await API.listPasswords('model+tags'),
            queue     = [];

        this._sendStatus('passwords', 'processing', Object.keys(passwords).length);
        for(let id in passwords) {
            if(!passwords.hasOwnProperty(id)) continue;
            let password = passwords[id];

            queue.push(this._encryptPassword(password, folderMap, tagMap));

            if(queue.length > 15) {
                await Promise.all(queue);
                queue = [];
            }
        }

        if(queue.length !== 0) await Promise.all(queue);
        this._sendStatus('passwords', 'done');
    }

    /**
     *
     * @param password
     * @param folderMap
     * @param tagMap
     * @param current
     * @param total
     * @returns {Promise<void>}
     * @private
     */
    async _encryptPassword(password, folderMap, tagMap, current, total) {
        password.folder = folderMap[password.folder];

        let tags = [];
        for(let id in password.tags) {
            if(!password.tags.hasOwnProperty(id)) continue;
            tags.push(tagMap[id]);
        }
        password.tags = tags;

        if(!password.shared) {
            await this._deleteObject(password.id, 'password');
            password.cseType = 'CSEv1r1';

            try {
                await API.createPassword(password);
                console.log(`Encrypted password ${password.id}`);
                this._sendStatus('passwords');
            } catch(e) {
                this._sendStatus('passwords', 'error', e);
                throw e;
            }
        } else {
            try {
                await API.updatePassword(password);
                console.log(`Updated password ${password.id}`);
                this._sendStatus('passwords');
            } catch(e) {<commit_msg>Do not e2e passwords shared with the user<commit_after>import API from "@js/Helper/api";
import Utility from '@js/Classes/Utility';
import Messages from '@js/Classes/Messages';
import Application from '@js/Init/Application';
import Localisation from '@js/Classes/Localisation';
import EventManager from '@js/Manager/EventManager';
import SettingsService from "@js/Services/SettingsService";

class EncryptionManager {

    constructor() {
        this._statusFunc = null;
        this.status = null;
    }

    /**
     *
     * @param password
     * @param save
     * @param encrypt
     * @param statusFunc
     */
    async install(password, save = false, encrypt = false, statusFunc = null) {
        this._resetStatus(statusFunc);
        await this._updateKeychain(password);

        if(encrypt !== false) {
            let tagMap    = {},
                folderMap = {};

            await Promise.all(
                [
                    this._encryptTags(tagMap),
                    this._encryptFolders(folderMap)
                ]
            );

            await this._encryptPasswords(folderMap, tagMap);
            await this._cleanDatabase(tagMap, folderMap);
        }

        if(save) await this._saveMasterPassword(password);
        Application.loginRequired = true;
    }

    /**
     *
     * @param password
     * @param oldPassword
     * @returns {Promise<void>}
     */
    async update(password, oldPassword) {
        try {
            await API.setAccountChallenge(password, oldPassword);
        } catch(e) {
            throw e;
        }
    }

    /**
     *
     * @returns {Promise<void>}
     */
    async updateGui() {
        let data = await Messages.form(
            {
                password      : {
                    label    : 'New password',
                    type     : 'password',
                    button   : 'toggle',
                    minlength: 12,
                    required : true,
                    title    : 'Your password must be longer than 12 characters and not the old password',
                    validator: (value, fields) => {
                        return value !== fields.oldPassword && value.length >= 12;
                    }
                },
                repeatPassword: {
                    label    : 'Repeat password',
                    type     : 'password',
                    button   : 'toggle',
                    required : true,
                    title    : 'Please confirm your new password',
                    validator: (value, fields) => {
                        return value === fields.password;
                    }
                },
                oldPassword   : {
                    label    : 'Old password',
                    type     : 'password',
                    button   : 'toggle',
                    title    : 'You must enter your old password',
                    required : true,
                    validator: (value) => {
                        return value.length >= 12;
                    }
                }
            },
            'Change Password',
            'You can use this dialog to change your master password.'
        );

        try {
            this._lockApp();
            await this.update(data.password, data.oldPassword);
            this._unlockApp();

            Messages.alert('Your password has been changed successfully.', 'Password changed');
        } catch(e) {
            this._unlockApp();
            Messages.alert(e.message, 'Changing password failed');
            console.error(e);
        }
    }

    /**
     *
     * @param password
     * @returns {Promise<void>}
     * @private
     */
    async _updateKeychain(password) {
        this._sendStatus('keychain', 'processing', 1);
        try {
            await API.setAccountChallenge(password);
            await Promise.all([await SettingsService.reset('user.encryption.cse'), await SettingsService.reset('user.encryption.sse')]);
            this._sendStatus('keychain', 'done');
        } catch(e) {
            this._sendStatus('keychain', 'error', e);
            throw e;
        }
    }

    /**
     *
     * @param folderMap
     * @param tagMap
     * @returns {Promise<void>}
     * @private
     */
    async _encryptPasswords(folderMap, tagMap) {
        this._sendStatus('passwords', 'loading');
        let passwords = await API.listPasswords('model+tags'),
            queue     = [];

        this._sendStatus('passwords', 'processing', Object.keys(passwords).length);
        for(let id in passwords) {
            if(!passwords.hasOwnProperty(id)) continue;
            let password = passwords[id];

            queue.push(this._encryptPassword(password, folderMap, tagMap));

            if(queue.length > 15) {
                await Promise.all(queue);
                queue = [];
            }
        }

        if(queue.length !== 0) await Promise.all(queue);
        this._sendStatus('passwords', 'done');
    }

    /**
     *
     * @param password
     * @param folderMap
     * @param tagMap
     * @param current
     * @param total
     * @returns {Promise<void>}
     * @private
     */
    async _encryptPassword(password, folderMap, tagMap, current, total) {
        password.folder = folderMap[password.folder];

        let tags = [];
        for(let id in password.tags) {
            if(!password.tags.hasOwnProperty(id)) continue;
            tags.push(tagMap[id]);
        }
        password.tags = tags;

        if(!password.shared && password.share === null) {
            await this._deleteObject(password.id, 'password');
            password.cseType = 'CSEv1r1';

            try {
                await API.createPassword(password);
                console.log(`Encrypted password ${password.id}`);
                this._sendStatus('passwords');
            } catch(e) {
                this._sendStatus('passwords', 'error', e);
                throw e;
            }
        } else {
            try {
                await API.updatePassword(password);
                console.log(`Updated password ${password.id}`);
                this._sendStatus('passwords');
            } catch(e) {
{'fraction_non_alphanumeric': 0.113192248439147, 'fraction_numerical': 0.0023514149031054893, 'mean_word_length': 1.4712482468443198, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7641639', 'n_tokens_mistral': 3217, 'n_tokens_neox': 3073, 'n_words': 685}