
* refactor(Notification): use instance methods * refactor(Audio): move to lib layer * refactor(EncryptionService): rename instance to encryption * refactor(ConnectionTest): move to lib * refactor(FileTransfer): move to lib * refactor(PeerRoom): move to lib * refactor(sleep): move to lib * refactor(type-guards): move to lib * refactor(SerializationService): use standard instance name * refactor(SettingsService): use standard instance name
82 lines
2.2 KiB
TypeScript
82 lines
2.2 KiB
TypeScript
import { saveAs } from 'file-saver'
|
|
|
|
import { UserSettings } from 'models/settings'
|
|
import { encryption } from 'services/Encryption'
|
|
import {
|
|
isSerializedUserSettings,
|
|
serialization,
|
|
} from 'services/Serialization/Serialization'
|
|
|
|
class InvalidFileError extends Error {
|
|
message = 'InvalidFileError: File could not be imported'
|
|
}
|
|
|
|
const encryptionTestTarget = 'chitchatter'
|
|
|
|
export class SettingsService {
|
|
exportSettings = async (userSettings: UserSettings) => {
|
|
const serializedUserSettings = await serialization.serializeUserSettings(
|
|
userSettings
|
|
)
|
|
|
|
const blob = new Blob([JSON.stringify(serializedUserSettings)], {
|
|
type: 'application/json;charset=utf-8',
|
|
})
|
|
|
|
saveAs(blob, `chitchatter-profile-${userSettings.userId}.json`)
|
|
}
|
|
|
|
importSettings = async (file: File) => {
|
|
const fileReader = new FileReader()
|
|
|
|
const promise = new Promise<UserSettings>((resolve, reject) => {
|
|
fileReader.addEventListener('loadend', async evt => {
|
|
try {
|
|
const fileReaderResult = evt.target?.result
|
|
|
|
if (typeof fileReaderResult !== 'string') {
|
|
throw new Error()
|
|
}
|
|
|
|
const parsedFileResult = JSON.parse(fileReaderResult)
|
|
|
|
if (!isSerializedUserSettings(parsedFileResult)) {
|
|
throw new Error()
|
|
}
|
|
|
|
const deserializedUserSettings =
|
|
await serialization.deserializeUserSettings(parsedFileResult)
|
|
|
|
const encryptedString = await encryption.encryptString(
|
|
deserializedUserSettings.publicKey,
|
|
encryptionTestTarget
|
|
)
|
|
|
|
const decryptedString = await encryption.decryptString(
|
|
deserializedUserSettings.privateKey,
|
|
encryptedString
|
|
)
|
|
|
|
// NOTE: This determines whether the public and private keys match
|
|
// and are compatible with Chitchatter.
|
|
if (decryptedString !== encryptionTestTarget) {
|
|
throw new Error()
|
|
}
|
|
|
|
resolve(deserializedUserSettings)
|
|
} catch (e) {
|
|
const err = new InvalidFileError()
|
|
console.error(err)
|
|
reject(err)
|
|
}
|
|
})
|
|
|
|
fileReader.readAsText(file.slice())
|
|
})
|
|
|
|
return promise
|
|
}
|
|
}
|
|
|
|
export const settings = new SettingsService()
|