241 lines
6.3 KiB
TypeScript
241 lines
6.3 KiB
TypeScript
/**
|
|
* Location implementation classes for Mail Manager services
|
|
*/
|
|
|
|
import type {
|
|
ServiceLocation,
|
|
ServiceLocationUri,
|
|
ServiceLocationSocketSole,
|
|
ServiceLocationSocketSplit,
|
|
ServiceLocationFile
|
|
} from '@/types/service';
|
|
|
|
/**
|
|
* Base Location class
|
|
*/
|
|
export abstract class Location {
|
|
abstract toJson(): ServiceLocation;
|
|
|
|
static fromJson(data: ServiceLocation): Location {
|
|
switch (data.type) {
|
|
case 'URI':
|
|
return LocationUri.fromJson(data);
|
|
case 'SOCKET_SOLE':
|
|
return LocationSocketSole.fromJson(data);
|
|
case 'SOCKET_SPLIT':
|
|
return LocationSocketSplit.fromJson(data);
|
|
case 'FILE':
|
|
return LocationFile.fromJson(data);
|
|
default:
|
|
throw new Error(`Unknown location type: ${(data as any).type}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* URI-based service location for API and web services
|
|
* Used by: JMAP, Gmail API, etc.
|
|
*/
|
|
export class LocationUri extends Location {
|
|
readonly type = 'URI' as const;
|
|
scheme: string;
|
|
host: string;
|
|
port: number;
|
|
path?: string;
|
|
verifyPeer: boolean;
|
|
verifyHost: boolean;
|
|
|
|
constructor(
|
|
scheme: string = 'https',
|
|
host: string = '',
|
|
port: number = 443,
|
|
path?: string,
|
|
verifyPeer: boolean = true,
|
|
verifyHost: boolean = true
|
|
) {
|
|
super();
|
|
this.scheme = scheme;
|
|
this.host = host;
|
|
this.port = port;
|
|
this.path = path;
|
|
this.verifyPeer = verifyPeer;
|
|
this.verifyHost = verifyHost;
|
|
}
|
|
|
|
static fromJson(data: ServiceLocationUri): LocationUri {
|
|
return new LocationUri(
|
|
data.scheme,
|
|
data.host,
|
|
data.port,
|
|
data.path,
|
|
data.verifyPeer ?? true,
|
|
data.verifyHost ?? true
|
|
);
|
|
}
|
|
|
|
toJson(): ServiceLocationUri {
|
|
return {
|
|
type: this.type,
|
|
scheme: this.scheme,
|
|
host: this.host,
|
|
port: this.port,
|
|
...(this.path && { path: this.path }),
|
|
...(this.verifyPeer !== undefined && { verifyPeer: this.verifyPeer }),
|
|
...(this.verifyHost !== undefined && { verifyHost: this.verifyHost })
|
|
};
|
|
}
|
|
|
|
getUrl(): string {
|
|
const path = this.path || '';
|
|
return `${this.scheme}://${this.host}:${this.port}${path}`;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Single socket-based service location
|
|
* Used by: services using a single host/port combination
|
|
*/
|
|
export class LocationSocketSole extends Location {
|
|
readonly type = 'SOCKET_SOLE' as const;
|
|
host: string;
|
|
port: number;
|
|
encryption: 'none' | 'ssl' | 'tls' | 'starttls';
|
|
verifyPeer: boolean;
|
|
verifyHost: boolean;
|
|
|
|
constructor(
|
|
host: string = '',
|
|
port: number = 993,
|
|
encryption: 'none' | 'ssl' | 'tls' | 'starttls' = 'ssl',
|
|
verifyPeer: boolean = true,
|
|
verifyHost: boolean = true
|
|
) {
|
|
super();
|
|
this.host = host;
|
|
this.port = port;
|
|
this.encryption = encryption;
|
|
this.verifyPeer = verifyPeer;
|
|
this.verifyHost = verifyHost;
|
|
}
|
|
|
|
static fromJson(data: ServiceLocationSocketSole): LocationSocketSole {
|
|
return new LocationSocketSole(
|
|
data.host,
|
|
data.port,
|
|
data.encryption,
|
|
data.verifyPeer ?? true,
|
|
data.verifyHost ?? true
|
|
);
|
|
}
|
|
|
|
toJson(): ServiceLocationSocketSole {
|
|
return {
|
|
type: this.type,
|
|
host: this.host,
|
|
port: this.port,
|
|
encryption: this.encryption,
|
|
...(this.verifyPeer !== undefined && { verifyPeer: this.verifyPeer }),
|
|
...(this.verifyHost !== undefined && { verifyHost: this.verifyHost })
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Split socket-based service location
|
|
* Used by: traditional IMAP/SMTP configurations
|
|
*/
|
|
export class LocationSocketSplit extends Location {
|
|
readonly type = 'SOCKET_SPLIT' as const;
|
|
inboundHost: string;
|
|
inboundPort: number;
|
|
inboundEncryption: 'none' | 'ssl' | 'tls' | 'starttls';
|
|
outboundHost: string;
|
|
outboundPort: number;
|
|
outboundEncryption: 'none' | 'ssl' | 'tls' | 'starttls';
|
|
inboundVerifyPeer: boolean;
|
|
inboundVerifyHost: boolean;
|
|
outboundVerifyPeer: boolean;
|
|
outboundVerifyHost: boolean;
|
|
|
|
constructor(
|
|
inboundHost: string = '',
|
|
inboundPort: number = 993,
|
|
inboundEncryption: 'none' | 'ssl' | 'tls' | 'starttls' = 'ssl',
|
|
outboundHost: string = '',
|
|
outboundPort: number = 465,
|
|
outboundEncryption: 'none' | 'ssl' | 'tls' | 'starttls' = 'ssl',
|
|
inboundVerifyPeer: boolean = true,
|
|
inboundVerifyHost: boolean = true,
|
|
outboundVerifyPeer: boolean = true,
|
|
outboundVerifyHost: boolean = true
|
|
) {
|
|
super();
|
|
this.inboundHost = inboundHost;
|
|
this.inboundPort = inboundPort;
|
|
this.inboundEncryption = inboundEncryption;
|
|
this.outboundHost = outboundHost;
|
|
this.outboundPort = outboundPort;
|
|
this.outboundEncryption = outboundEncryption;
|
|
this.inboundVerifyPeer = inboundVerifyPeer;
|
|
this.inboundVerifyHost = inboundVerifyHost;
|
|
this.outboundVerifyPeer = outboundVerifyPeer;
|
|
this.outboundVerifyHost = outboundVerifyHost;
|
|
}
|
|
|
|
static fromJson(data: ServiceLocationSocketSplit): LocationSocketSplit {
|
|
return new LocationSocketSplit(
|
|
data.inboundHost,
|
|
data.inboundPort,
|
|
data.inboundEncryption,
|
|
data.outboundHost,
|
|
data.outboundPort,
|
|
data.outboundEncryption,
|
|
data.inboundVerifyPeer ?? true,
|
|
data.inboundVerifyHost ?? true,
|
|
data.outboundVerifyPeer ?? true,
|
|
data.outboundVerifyHost ?? true
|
|
);
|
|
}
|
|
|
|
toJson(): ServiceLocationSocketSplit {
|
|
return {
|
|
type: this.type,
|
|
inboundHost: this.inboundHost,
|
|
inboundPort: this.inboundPort,
|
|
inboundEncryption: this.inboundEncryption,
|
|
outboundHost: this.outboundHost,
|
|
outboundPort: this.outboundPort,
|
|
outboundEncryption: this.outboundEncryption,
|
|
...(this.inboundVerifyPeer !== undefined && { inboundVerifyPeer: this.inboundVerifyPeer }),
|
|
...(this.inboundVerifyHost !== undefined && { inboundVerifyHost: this.inboundVerifyHost }),
|
|
...(this.outboundVerifyPeer !== undefined && { outboundVerifyPeer: this.outboundVerifyPeer }),
|
|
...(this.outboundVerifyHost !== undefined && { outboundVerifyHost: this.outboundVerifyHost })
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* File-based service location
|
|
* Used by: local file system providers
|
|
*/
|
|
export class LocationFile extends Location {
|
|
readonly type = 'FILE' as const;
|
|
path: string;
|
|
|
|
constructor(path: string = '') {
|
|
super();
|
|
this.path = path;
|
|
}
|
|
|
|
static fromJson(data: ServiceLocationFile): LocationFile {
|
|
return new LocationFile(data.path);
|
|
}
|
|
|
|
toJson(): ServiceLocationFile {
|
|
return {
|
|
type: this.type,
|
|
path: this.path
|
|
};
|
|
}
|
|
}
|