Files
standardnotes-app-web/packages/ui-services/src/Import/AegisConverter/AegisToAuthenticatorConverter.ts

98 lines
2.6 KiB
TypeScript

import { DecryptedTransferPayload, NoteContent } from '@standardnotes/models'
import { readFileAsText } from '../Utils'
import { NativeFeatureIdentifier, NoteType } from '@standardnotes/features'
import { ContentType } from '@standardnotes/domain-core'
import { GenerateUuid } from '@standardnotes/services'
type AegisData = {
db: {
entries: {
issuer: string
name: string
info: {
secret: string
}
note: string
}[]
}
}
const AegisEntryTypes = ['hotp', 'totp', 'steam', 'yandex'] as const
type AuthenticatorEntry = {
service: string
account: string
secret: string
notes: string
}
export class AegisToAuthenticatorConverter {
constructor(private _generateUuid: GenerateUuid) {}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static isValidAegisJson(json: any): boolean {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return json.db && json.db.entries && json.db.entries.every((entry: any) => AegisEntryTypes.includes(entry.type))
}
async convertAegisBackupFileToNote(
file: File,
addEditorInfo: boolean,
): Promise<DecryptedTransferPayload<NoteContent>> {
const content = await readFileAsText(file)
const entries = this.parseEntries(content)
if (!entries) {
throw new Error('Could not parse entries')
}
return this.createNoteFromEntries(entries, file, addEditorInfo)
}
createNoteFromEntries(
entries: AuthenticatorEntry[],
file: {
lastModified: number
name: string
},
addEditorInfo: boolean,
): DecryptedTransferPayload<NoteContent> {
return {
created_at: new Date(file.lastModified),
created_at_timestamp: file.lastModified,
updated_at: new Date(file.lastModified),
updated_at_timestamp: file.lastModified,
uuid: this._generateUuid.execute().getValue(),
content_type: ContentType.TYPES.Note,
content: {
title: file.name.split('.')[0],
text: JSON.stringify(entries),
references: [],
...(addEditorInfo && {
noteType: NoteType.Authentication,
editorIdentifier: NativeFeatureIdentifier.TYPES.TokenVaultEditor,
}),
},
}
}
parseEntries(data: string): AuthenticatorEntry[] | null {
try {
const json = JSON.parse(data) as AegisData
const entries = json.db.entries.map((entry) => {
return {
service: entry.issuer,
account: entry.name,
secret: entry.info.secret,
notes: entry.note,
} as AuthenticatorEntry
})
return entries
} catch (error) {
console.error(error)
return null
}
}
}