refactor(dev-only): import tools (#2121)

This commit is contained in:
Aman Harwara
2022-12-27 21:03:01 +05:30
committed by GitHub
parent e67240821c
commit 3fbe28e068
24 changed files with 1267 additions and 1 deletions

View File

@@ -0,0 +1,89 @@
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
import { WebApplicationInterface } from '@standardnotes/services'
import { AegisToAuthenticatorConverter } from './AegisToAuthenticatorConverter'
import data from './testData'
describe('AegisConverter', () => {
let application: WebApplicationInterface
beforeEach(() => {
application = {
generateUUID: jest.fn().mockReturnValue('test'),
} as unknown as WebApplicationInterface
})
it('should parse entries', () => {
const converter = new AegisToAuthenticatorConverter(application)
const result = converter.parseEntries(data)
expect(result).not.toBeNull()
expect(result?.length).toBe(2)
expect(result?.[0]).toStrictEqual({
service: 'TestMail',
account: 'test@test.com',
secret: 'TESTMAILTESTMAILTESTMAILTESTMAIL',
notes: 'Some note',
})
expect(result?.[1]).toStrictEqual({
service: 'Some Service',
account: 'test@test.com',
secret: 'SOMESERVICESOMESERVICESOMESERVIC',
notes: 'Some other service',
})
})
it('should create note from entries with editor info', () => {
const converter = new AegisToAuthenticatorConverter(application)
const parsedEntries = converter.parseEntries(data)
const result = converter.createNoteFromEntries(
parsedEntries!,
{
lastModified: 123456789,
name: 'test.json',
},
true,
)
expect(result).not.toBeNull()
expect(result.content_type).toBe('Note')
expect(result.created_at).toBeInstanceOf(Date)
expect(result.updated_at).toBeInstanceOf(Date)
expect(result.uuid).not.toBeNull()
expect(result.content.title).toBe('test')
expect(result.content.text).toBe(
'[{"service":"TestMail","account":"test@test.com","secret":"TESTMAILTESTMAILTESTMAILTESTMAIL","notes":"Some note"},{"service":"Some Service","account":"test@test.com","secret":"SOMESERVICESOMESERVICESOMESERVIC","notes":"Some other service"}]',
)
expect(result.content.noteType).toBe(NoteType.Authentication)
expect(result.content.editorIdentifier).toBe(FeatureIdentifier.TokenVaultEditor)
})
it('should create note from entries without editor info', () => {
const converter = new AegisToAuthenticatorConverter(application)
const parsedEntries = converter.parseEntries(data)
const result = converter.createNoteFromEntries(
parsedEntries!,
{
lastModified: 123456789,
name: 'test.json',
},
false,
)
expect(result).not.toBeNull()
expect(result.content_type).toBe('Note')
expect(result.created_at).toBeInstanceOf(Date)
expect(result.updated_at).toBeInstanceOf(Date)
expect(result.uuid).not.toBeNull()
expect(result.content.title).toBe('test')
expect(result.content.text).toBe(
'[{"service":"TestMail","account":"test@test.com","secret":"TESTMAILTESTMAILTESTMAILTESTMAIL","notes":"Some note"},{"service":"Some Service","account":"test@test.com","secret":"SOMESERVICESOMESERVICESOMESERVIC","notes":"Some other service"}]',
)
expect(result.content.noteType).toBeFalsy()
expect(result.content.editorIdentifier).toBeFalsy()
})
})

View File

@@ -0,0 +1,92 @@
import { DecryptedTransferPayload, NoteContent } from '@standardnotes/models'
import { ContentType } from '@standardnotes/common'
import { readFileAsText } from '../Utils'
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
import { WebApplicationInterface } from '@standardnotes/services'
import { Importer } from '../Importer'
type AegisData = {
db: {
entries: {
issuer: string
name: string
info: {
secret: string
}
note: string
}[]
}
}
type AuthenticatorEntry = {
service: string
account: string
secret: string
notes: string
}
export class AegisToAuthenticatorConverter extends Importer {
constructor(protected override application: WebApplicationInterface) {
super(application)
}
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.application.generateUUID(),
content_type: ContentType.Note,
content: {
title: file.name.split('.')[0],
text: JSON.stringify(entries),
references: [],
...(addEditorInfo && {
noteType: NoteType.Authentication,
editorIdentifier: FeatureIdentifier.TokenVaultEditor,
}),
},
}
}
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)
}
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
}
}
}

View File

@@ -0,0 +1,42 @@
const data = {
version: 1,
header: {
slots: null,
params: null,
},
db: {
version: 2,
entries: [
{
type: 'totp',
uuid: 'c74a11c4-4f23-417b-818a-e11f6a4d51d7',
name: 'test@test.com',
issuer: 'TestMail',
note: 'Some note',
icon: null,
info: {
secret: 'TESTMAILTESTMAILTESTMAILTESTMAIL',
algo: 'SHA1',
digits: 6,
period: 30,
},
},
{
type: 'totp',
uuid: '803ed58f-b2c4-386c-9aad-645a47309124',
name: 'test@test.com',
issuer: 'Some Service',
note: 'Some other service',
icon: null,
info: {
secret: 'SOMESERVICESOMESERVICESOMESERVIC',
algo: 'SHA1',
digits: 6,
period: 30,
},
},
],
},
}
export default JSON.stringify(data, null, 2)