Files
identity/IdentityFactory.ts
Chris Daßler a6b10428fa Initial commit: Identity management component
- Hierarchical user/device identity system with HD key derivation
- Dependency injection for AsyncStorage and Platform
- Self-contained TypeScript declarations
- Ed25519 keypairs managed by IdentityManager
- Deterministic peer ID generation from BIP39 mnemonic
2025-08-29 14:17:39 +02:00

119 lines
3.5 KiB
TypeScript

/**
* Factory for creating identity manager instances
*/
import { LoggerComponent } from 'ior:gitea:gitea.metatrom.net:universal-components/logger@1.0.0';
import { AsyncStorageAdapter } from './implementations/AsyncStorageAdapter';
import { IdentityManager } from './implementations/IdentityManager';
import type {
IdentityConfig,
IIdentityFactory,
IIdentityManager,
IIdentityStorage,
} from './interfaces/IIdentity';
// Platform interface for dependency injection
interface IPlatform {
OS: string;
}
export class IdentityFactory implements IIdentityFactory {
private static instance?: IdentityFactory;
private identityManager?: IIdentityManager;
private storage?: IIdentityStorage;
private logger = new LoggerComponent('IdentityFactory');
private platform?: IPlatform;
private asyncStorage?: any;
private constructor(platform?: IPlatform, asyncStorage?: any) {
this.platform = platform;
this.asyncStorage = asyncStorage;
}
static getInstance(platform?: IPlatform, asyncStorage?: any): IdentityFactory {
if (!IdentityFactory.instance) {
IdentityFactory.instance = new IdentityFactory(platform, asyncStorage);
}
return IdentityFactory.instance;
}
create(config?: IdentityConfig): IIdentityManager {
// Use singleton pattern for identity manager
if (!this.identityManager) {
const storage = this.getStorage();
// Enhanced config with platform-specific device name provider
const enhancedConfig: IdentityConfig = {
...config,
deviceNameProvider: config?.deviceNameProvider || this.getDeviceNameProvider(),
};
this.identityManager = new IdentityManager(storage, enhancedConfig);
}
return this.identityManager;
}
private getStorage(): IIdentityStorage {
if (!this.storage) {
if (!this.asyncStorage) {
throw new Error('AsyncStorage not provided. Please provide AsyncStorage when creating the factory.');
}
// Use AsyncStorage for React Native
this.storage = new AsyncStorageAdapter(this.asyncStorage);
}
return this.storage;
}
private getDeviceNameProvider(): () => Promise<string> {
return async () => {
try {
// Try to use react-native-device-info if available
const DeviceInfo = require('react-native-device-info').default;
if (DeviceInfo?.getDeviceName) {
const name = await DeviceInfo.getDeviceName();
return name || this.getFallbackDeviceName();
}
} catch (_error) {
// Module not available, use fallback
this.logger.debug('react-native-device-info not available, using fallback device name');
}
return this.getFallbackDeviceName();
};
}
private getFallbackDeviceName(): string {
const platform = this.platform?.OS || 'unknown';
const timestamp = Date.now().toString(36).substring(-4);
switch (platform) {
case 'ios':
return `iPhone-${timestamp}`;
case 'android':
return `Android-${timestamp}`;
default:
return `Device-${timestamp}`;
}
}
/**
* Reset the singleton instance (useful for testing)
*/
static reset(): void {
if (IdentityFactory.instance?.identityManager) {
IdentityFactory.instance.identityManager = undefined;
}
IdentityFactory.instance = undefined;
}
}
// Export singleton instance creator with dependency injection
export const createIdentityManager = (
config?: IdentityConfig,
platform?: IPlatform,
asyncStorage?: any
): IIdentityManager => {
return IdentityFactory.getInstance(platform, asyncStorage).create(config);
};