chore: fix uuid generation for importers
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
LegacyApiServiceInterface,
|
||||
StatusServiceInterface,
|
||||
MfaServiceInterface,
|
||||
GenerateUuid,
|
||||
} from '@standardnotes/services'
|
||||
import { VaultLockServiceInterface } from './../VaultLock/VaultLockServiceInterface'
|
||||
import { HistoryServiceInterface } from './../History/HistoryServiceInterface'
|
||||
@@ -85,6 +86,7 @@ export interface ApplicationInterface {
|
||||
get files(): FilesClientInterface
|
||||
get history(): HistoryServiceInterface
|
||||
get homeServer(): HomeServerServiceInterface | undefined
|
||||
get generateUuid(): GenerateUuid
|
||||
get items(): ItemManagerInterface
|
||||
get legacyApi(): LegacyApiServiceInterface
|
||||
get mfa(): MfaServiceInterface
|
||||
|
||||
12
packages/services/src/Domain/UseCase/GenerateUuid.ts
Normal file
12
packages/services/src/Domain/UseCase/GenerateUuid.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Result, SyncUseCaseInterface } from '@standardnotes/domain-core'
|
||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||
|
||||
export class GenerateUuid implements SyncUseCaseInterface<string> {
|
||||
constructor(private crypto: PureCryptoInterface) {}
|
||||
|
||||
execute(): Result<string> {
|
||||
const uuid = this.crypto.generateUUID()
|
||||
|
||||
return Result.ok(uuid)
|
||||
}
|
||||
}
|
||||
@@ -178,6 +178,7 @@ export * from './Sync/SyncServiceInterface'
|
||||
export * from './Sync/SyncSource'
|
||||
export * from './UseCase/ChangeAndSaveItem'
|
||||
export * from './UseCase/DiscardItemsLocally'
|
||||
export * from './UseCase/GenerateUuid'
|
||||
export * from './UseCase/GetHost'
|
||||
export * from './UseCase/SetHost'
|
||||
export * from './User/AccountEvent'
|
||||
|
||||
@@ -81,6 +81,7 @@ import {
|
||||
GetHost,
|
||||
SetHost,
|
||||
MfaServiceInterface,
|
||||
GenerateUuid,
|
||||
} from '@standardnotes/services'
|
||||
import {
|
||||
SNNote,
|
||||
@@ -112,7 +113,6 @@ import {
|
||||
removeFromArray,
|
||||
isNullOrUndefined,
|
||||
sleep,
|
||||
UuidGenerator,
|
||||
useBoolean,
|
||||
LoggerInterface,
|
||||
canBlockDeinit,
|
||||
@@ -932,10 +932,6 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
||||
return this.migrations.hasPendingMigrations()
|
||||
}
|
||||
|
||||
public generateUuid(): string {
|
||||
return UuidGenerator.GenerateUuid()
|
||||
}
|
||||
|
||||
public presentKeyRecoveryWizard(): void {
|
||||
const service = this.dependencies.get<KeyRecoveryService>(TYPES.KeyRecoveryService)
|
||||
return service.presentKeyRecoveryWizard()
|
||||
@@ -1243,6 +1239,10 @@ export class SNApplication implements ApplicationInterface, AppGroupManagedAppli
|
||||
return this.dependencies.get<MfaService>(TYPES.MfaService)
|
||||
}
|
||||
|
||||
public get generateUuid(): GenerateUuid {
|
||||
return this.dependencies.get<GenerateUuid>(TYPES.GenerateUuid)
|
||||
}
|
||||
|
||||
private get migrations(): MigrationService {
|
||||
return this.dependencies.get<MigrationService>(TYPES.MigrationService)
|
||||
}
|
||||
|
||||
@@ -130,6 +130,7 @@ import {
|
||||
FullyResolvedApplicationOptions,
|
||||
GetHost,
|
||||
SetHost,
|
||||
GenerateUuid,
|
||||
} from '@standardnotes/services'
|
||||
import { ItemManager } from '../../Services/Items/ItemManager'
|
||||
import { PayloadManager } from '../../Services/Payloads/PayloadManager'
|
||||
@@ -214,6 +215,10 @@ export class Dependencies {
|
||||
}
|
||||
|
||||
private registerUseCaseMakers() {
|
||||
this.factory.set(TYPES.GenerateUuid, () => {
|
||||
return new GenerateUuid(this.get<PureCryptoInterface>(TYPES.Crypto))
|
||||
})
|
||||
|
||||
this.factory.set(TYPES.DecryptErroredPayloads, () => {
|
||||
return new DecryptErroredPayloads(
|
||||
this.get<ItemsEncryptionService>(TYPES.ItemsEncryptionService),
|
||||
|
||||
@@ -159,6 +159,7 @@ export const TYPES = {
|
||||
ChangeAndSaveItem: Symbol.for('ChangeAndSaveItem'),
|
||||
GetHost: Symbol.for('GetHost'),
|
||||
SetHost: Symbol.for('SetHost'),
|
||||
GenerateUuid: Symbol.for('GenerateUuid'),
|
||||
|
||||
// Mappers
|
||||
SessionStorageMapper: Symbol.for('SessionStorageMapper'),
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||
import { NativeFeatureIdentifier, NoteType } from '@standardnotes/features'
|
||||
import { AegisToAuthenticatorConverter } from './AegisToAuthenticatorConverter'
|
||||
import data from './testData'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
|
||||
UuidGenerator.SetGenerator(() => String(Math.random()))
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
describe('AegisConverter', () => {
|
||||
const crypto = {
|
||||
generateUUID: () => String(Math.random()),
|
||||
} as unknown as PureCryptoInterface
|
||||
|
||||
const generateUuid = new GenerateUuid(crypto)
|
||||
|
||||
it('should parse entries', () => {
|
||||
const converter = new AegisToAuthenticatorConverter()
|
||||
const converter = new AegisToAuthenticatorConverter(generateUuid)
|
||||
|
||||
const result = converter.parseEntries(data)
|
||||
|
||||
@@ -28,7 +33,7 @@ describe('AegisConverter', () => {
|
||||
})
|
||||
|
||||
it('should create note from entries with editor info', () => {
|
||||
const converter = new AegisToAuthenticatorConverter()
|
||||
const converter = new AegisToAuthenticatorConverter(generateUuid)
|
||||
|
||||
const parsedEntries = converter.parseEntries(data)
|
||||
|
||||
@@ -55,7 +60,7 @@ describe('AegisConverter', () => {
|
||||
})
|
||||
|
||||
it('should create note from entries without editor info', () => {
|
||||
const converter = new AegisToAuthenticatorConverter()
|
||||
const converter = new AegisToAuthenticatorConverter(generateUuid)
|
||||
|
||||
const parsedEntries = converter.parseEntries(data)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { DecryptedTransferPayload, NoteContent } from '@standardnotes/models'
|
||||
import { readFileAsText } from '../Utils'
|
||||
import { NativeFeatureIdentifier, NoteType } from '@standardnotes/features'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
type AegisData = {
|
||||
db: {
|
||||
@@ -27,7 +27,7 @@ type AuthenticatorEntry = {
|
||||
}
|
||||
|
||||
export class AegisToAuthenticatorConverter {
|
||||
constructor() {}
|
||||
constructor(private _generateUuid: GenerateUuid) {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static isValidAegisJson(json: any): boolean {
|
||||
@@ -63,7 +63,7 @@ export class AegisToAuthenticatorConverter {
|
||||
created_at_timestamp: file.lastModified,
|
||||
updated_at: new Date(file.lastModified),
|
||||
updated_at_timestamp: file.lastModified,
|
||||
uuid: UuidGenerator.GenerateUuid(),
|
||||
uuid: this._generateUuid.execute().getValue(),
|
||||
content_type: ContentType.TYPES.Note,
|
||||
content: {
|
||||
title: file.name.split('.')[0],
|
||||
|
||||
@@ -6,7 +6,8 @@ import { ContentType } from '@standardnotes/domain-core'
|
||||
import { DecryptedTransferPayload, NoteContent, TagContent } from '@standardnotes/models'
|
||||
import { EvernoteConverter } from './EvernoteConverter'
|
||||
import data from './testData'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
// Mock dayjs so dayjs.extend() doesn't throw an error in EvernoteConverter.ts
|
||||
jest.mock('dayjs', () => {
|
||||
@@ -21,11 +22,17 @@ jest.mock('dayjs', () => {
|
||||
}
|
||||
})
|
||||
|
||||
UuidGenerator.SetGenerator(() => String(Math.random()))
|
||||
|
||||
|
||||
describe('EvernoteConverter', () => {
|
||||
const crypto = {
|
||||
generateUUID: () => String(Math.random()),
|
||||
} as unknown as PureCryptoInterface
|
||||
|
||||
const generateUuid = new GenerateUuid(crypto)
|
||||
|
||||
it('should parse and strip html', () => {
|
||||
const converter = new EvernoteConverter()
|
||||
const converter = new EvernoteConverter(generateUuid)
|
||||
|
||||
const result = converter.parseENEXData(data, true)
|
||||
|
||||
@@ -45,7 +52,7 @@ describe('EvernoteConverter', () => {
|
||||
})
|
||||
|
||||
it('should parse and not strip html', () => {
|
||||
const converter = new EvernoteConverter()
|
||||
const converter = new EvernoteConverter(generateUuid)
|
||||
|
||||
const result = converter.parseENEXData(data, false)
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@ import dayjs from 'dayjs'
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat'
|
||||
import utc from 'dayjs/plugin/utc'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
dayjs.extend(customParseFormat)
|
||||
dayjs.extend(utc)
|
||||
|
||||
const dateFormat = 'YYYYMMDDTHHmmss'
|
||||
|
||||
export class EvernoteConverter {
|
||||
constructor() {}
|
||||
constructor(private _generateUuid: GenerateUuid) {}
|
||||
|
||||
async convertENEXFileToNotesAndTags(file: File, stripHTML: boolean): Promise<DecryptedTransferPayload[]> {
|
||||
const content = await readFileAsText(file)
|
||||
@@ -35,7 +35,7 @@ export class EvernoteConverter {
|
||||
created_at_timestamp: now.getTime(),
|
||||
updated_at: now,
|
||||
updated_at_timestamp: now.getTime(),
|
||||
uuid: UuidGenerator.GenerateUuid(),
|
||||
uuid: this._generateUuid.execute().getValue(),
|
||||
content_type: ContentType.TYPES.Tag,
|
||||
content: {
|
||||
title: defaultTagName,
|
||||
@@ -88,7 +88,7 @@ export class EvernoteConverter {
|
||||
created_at_timestamp: createdAtDate.getTime(),
|
||||
updated_at: updatedAtDate,
|
||||
updated_at_timestamp: updatedAtDate.getTime(),
|
||||
uuid: UuidGenerator.GenerateUuid(),
|
||||
uuid: this._generateUuid.execute().getValue(),
|
||||
content_type: ContentType.TYPES.Note,
|
||||
content: {
|
||||
title: !title ? `Imported note ${index + 1} from Evernote` : title,
|
||||
@@ -111,7 +111,7 @@ export class EvernoteConverter {
|
||||
if (!tag) {
|
||||
const now = new Date()
|
||||
tag = {
|
||||
uuid: UuidGenerator.GenerateUuid(),
|
||||
uuid: this._generateUuid.execute().getValue(),
|
||||
content_type: ContentType.TYPES.Tag,
|
||||
created_at: now,
|
||||
created_at_timestamp: now.getTime(),
|
||||
|
||||
@@ -4,13 +4,18 @@
|
||||
|
||||
import { jsonTestData, htmlTestData } from './testData'
|
||||
import { GoogleKeepConverter } from './GoogleKeepConverter'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
|
||||
UuidGenerator.SetGenerator(() => String(Math.random()))
|
||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
describe('GoogleKeepConverter', () => {
|
||||
const crypto = {
|
||||
generateUUID: () => String(Math.random()),
|
||||
} as unknown as PureCryptoInterface
|
||||
|
||||
const generateUuid = new GenerateUuid(crypto)
|
||||
|
||||
it('should parse json data', () => {
|
||||
const converter = new GoogleKeepConverter()
|
||||
const converter = new GoogleKeepConverter(generateUuid)
|
||||
|
||||
const result = converter.tryParseAsJson(jsonTestData)
|
||||
|
||||
@@ -27,7 +32,7 @@ describe('GoogleKeepConverter', () => {
|
||||
})
|
||||
|
||||
it('should parse html data', () => {
|
||||
const converter = new GoogleKeepConverter()
|
||||
const converter = new GoogleKeepConverter(generateUuid)
|
||||
|
||||
const result = converter.tryParseAsHtml(
|
||||
htmlTestData,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { DecryptedTransferPayload, NoteContent } from '@standardnotes/models'
|
||||
import { readFileAsText } from '../Utils'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
type GoogleKeepJsonNote = {
|
||||
color: string
|
||||
@@ -14,7 +14,7 @@ type GoogleKeepJsonNote = {
|
||||
}
|
||||
|
||||
export class GoogleKeepConverter {
|
||||
constructor() {}
|
||||
constructor(private _generateUuid: GenerateUuid) {}
|
||||
|
||||
async convertGoogleKeepBackupFileToNote(
|
||||
file: File,
|
||||
@@ -66,7 +66,7 @@ export class GoogleKeepConverter {
|
||||
created_at_timestamp: date.getTime(),
|
||||
updated_at: date,
|
||||
updated_at_timestamp: date.getTime(),
|
||||
uuid: UuidGenerator.GenerateUuid(),
|
||||
uuid: this._generateUuid.execute().getValue(),
|
||||
content_type: ContentType.TYPES.Note,
|
||||
content: {
|
||||
title: title,
|
||||
@@ -121,7 +121,7 @@ export class GoogleKeepConverter {
|
||||
created_at_timestamp: date.getTime(),
|
||||
updated_at: date,
|
||||
updated_at_timestamp: date.getTime(),
|
||||
uuid: UuidGenerator.GenerateUuid(),
|
||||
uuid: this._generateUuid.execute().getValue(),
|
||||
content_type: ContentType.TYPES.Note,
|
||||
content: {
|
||||
title: parsed.title,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { parseFileName } from '@standardnotes/filepicker'
|
||||
import {
|
||||
FeatureStatus,
|
||||
FeaturesClientInterface,
|
||||
GenerateUuid,
|
||||
ItemManagerInterface,
|
||||
MutatorClientInterface,
|
||||
} from '@standardnotes/services'
|
||||
@@ -27,12 +28,13 @@ export class Importer {
|
||||
private features: FeaturesClientInterface,
|
||||
private mutator: MutatorClientInterface,
|
||||
private items: ItemManagerInterface,
|
||||
_generateUuid: GenerateUuid,
|
||||
) {
|
||||
this.aegisConverter = new AegisToAuthenticatorConverter()
|
||||
this.googleKeepConverter = new GoogleKeepConverter()
|
||||
this.simplenoteConverter = new SimplenoteConverter()
|
||||
this.plaintextConverter = new PlaintextConverter()
|
||||
this.evernoteConverter = new EvernoteConverter()
|
||||
this.aegisConverter = new AegisToAuthenticatorConverter(_generateUuid)
|
||||
this.googleKeepConverter = new GoogleKeepConverter(_generateUuid)
|
||||
this.simplenoteConverter = new SimplenoteConverter(_generateUuid)
|
||||
this.plaintextConverter = new PlaintextConverter(_generateUuid)
|
||||
this.evernoteConverter = new EvernoteConverter(_generateUuid)
|
||||
}
|
||||
|
||||
static detectService = async (file: File): Promise<NoteImportType | null> => {
|
||||
|
||||
@@ -2,9 +2,11 @@ import { ContentType } from '@standardnotes/domain-core'
|
||||
import { parseFileName } from '@standardnotes/filepicker'
|
||||
import { DecryptedTransferPayload, NoteContent } from '@standardnotes/models'
|
||||
import { readFileAsText } from '../Utils'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
export class PlaintextConverter {
|
||||
constructor(private _generateUuid: GenerateUuid) {}
|
||||
|
||||
static isValidPlaintextFile(file: File): boolean {
|
||||
return file.type === 'text/plain' || file.type === 'text/markdown'
|
||||
}
|
||||
@@ -22,7 +24,7 @@ export class PlaintextConverter {
|
||||
created_at_timestamp: createdAtDate.getTime(),
|
||||
updated_at: updatedAtDate,
|
||||
updated_at_timestamp: updatedAtDate.getTime(),
|
||||
uuid: UuidGenerator.GenerateUuid(),
|
||||
uuid: this._generateUuid.execute().getValue(),
|
||||
content_type: ContentType.TYPES.Note,
|
||||
content: {
|
||||
title: name,
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
|
||||
import { SimplenoteConverter } from './SimplenoteConverter'
|
||||
import data from './testData'
|
||||
|
||||
UuidGenerator.SetGenerator(() => String(Math.random()))
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
describe('SimplenoteConverter', () => {
|
||||
const crypto = {
|
||||
generateUUID: () => String(Math.random()),
|
||||
} as unknown as PureCryptoInterface
|
||||
|
||||
const generateUuid = new GenerateUuid(crypto)
|
||||
|
||||
it('should parse', () => {
|
||||
const converter = new SimplenoteConverter()
|
||||
const converter = new SimplenoteConverter(generateUuid)
|
||||
|
||||
const result = converter.parse(data)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DecryptedTransferPayload, NoteContent } from '@standardnotes/models'
|
||||
import { ContentType } from '@standardnotes/domain-core'
|
||||
import { readFileAsText } from '../Utils'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
import { GenerateUuid } from '@standardnotes/services'
|
||||
|
||||
type SimplenoteItem = {
|
||||
creationDate: string
|
||||
@@ -18,7 +18,7 @@ type SimplenoteData = {
|
||||
const isSimplenoteEntry = (entry: any): boolean => entry.id && entry.content && entry.creationDate && entry.lastModified
|
||||
|
||||
export class SimplenoteConverter {
|
||||
constructor() {}
|
||||
constructor(private _generateUuid: GenerateUuid) {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static isValidSimplenoteJson(json: any): boolean {
|
||||
@@ -55,7 +55,7 @@ export class SimplenoteConverter {
|
||||
created_at_timestamp: createdAtDate.getTime(),
|
||||
updated_at: updatedAtDate,
|
||||
updated_at_timestamp: updatedAtDate.getTime(),
|
||||
uuid: UuidGenerator.GenerateUuid(),
|
||||
uuid: this._generateUuid.execute().getValue(),
|
||||
content_type: ContentType.TYPES.Note,
|
||||
content: {
|
||||
title,
|
||||
|
||||
@@ -56,7 +56,7 @@ export class WebDependencies extends DependencyContainer {
|
||||
super()
|
||||
|
||||
this.bind(Web_TYPES.Importer, () => {
|
||||
return new Importer(application.features, application.mutator, application.items)
|
||||
return new Importer(application.features, application.mutator, application.items, application.generateUuid)
|
||||
})
|
||||
|
||||
this.bind(Web_TYPES.IsNativeIOS, () => {
|
||||
|
||||
Reference in New Issue
Block a user