154 lines
4.2 KiB
TypeScript
154 lines
4.2 KiB
TypeScript
import * as plugins from './smartssh.plugins.js';
|
|
import * as helpers from './smartssh.classes.helpers.js';
|
|
|
|
export type TSshKeyType = 'duplex' | 'private' | 'public';
|
|
|
|
export class SshKey {
|
|
private _privKey: string;
|
|
private _pubKey: string;
|
|
private _hostVar: string;
|
|
private _authorized: boolean;
|
|
|
|
/**
|
|
* the constructor for class SshKey
|
|
*/
|
|
constructor(
|
|
optionsArg: { private?: string; public?: string; host?: string; authorized?: boolean } = {}
|
|
) {
|
|
this._privKey = optionsArg.private ?? '';
|
|
this._pubKey = optionsArg.public ?? '';
|
|
if (optionsArg.host) {
|
|
helpers.assertSafeHost(optionsArg.host);
|
|
}
|
|
this._hostVar = optionsArg.host ?? '';
|
|
this._authorized = optionsArg.authorized ?? false;
|
|
}
|
|
|
|
// this.host
|
|
get host() {
|
|
return this._hostVar;
|
|
}
|
|
set host(hostArg: string) {
|
|
if (hostArg) {
|
|
helpers.assertSafeHost(hostArg);
|
|
}
|
|
this._hostVar = hostArg;
|
|
}
|
|
|
|
// this.privKey
|
|
get privKey() {
|
|
return this._privKey;
|
|
}
|
|
set privKey(privateKeyArg: string) {
|
|
this._privKey = privateKeyArg;
|
|
}
|
|
|
|
// this.privKeyBase64
|
|
get privKeyBase64() {
|
|
return plugins.smartstring.base64.encode(this._privKey);
|
|
}
|
|
set privKeyBase64(privateKeyArg: string) {
|
|
this._privKey = plugins.smartstring.base64.decode(privateKeyArg);
|
|
}
|
|
|
|
// this.pubKey
|
|
get pubKey() {
|
|
return this._pubKey;
|
|
}
|
|
set pubKey(publicKeyArg: string) {
|
|
this._pubKey = publicKeyArg;
|
|
}
|
|
|
|
// this.pubKeyBase64
|
|
get pubKeyBase64() {
|
|
return plugins.smartstring.base64.encode(this._pubKey);
|
|
}
|
|
set pubKeyBase64(publicKeyArg: string) {
|
|
this._pubKey = plugins.smartstring.base64.decode(publicKeyArg);
|
|
}
|
|
|
|
get authorized() {
|
|
return this._authorized;
|
|
}
|
|
set authorized(authorizedArg: boolean) {
|
|
this._authorized = authorizedArg;
|
|
}
|
|
|
|
/**
|
|
* returns wether there is a private, a public or both keys
|
|
*/
|
|
get type(): TSshKeyType | undefined {
|
|
if (this._privKey && this._pubKey) {
|
|
return 'duplex';
|
|
} else if (this._privKey) {
|
|
return 'private';
|
|
} else if (this._pubKey) {
|
|
return 'public';
|
|
}
|
|
}
|
|
|
|
// methods
|
|
read(filePathArg: string) {
|
|
const resolvedPath = plugins.path.resolve(filePathArg);
|
|
const fileName = plugins.path.basename(resolvedPath);
|
|
const isPublicKey = fileName.endsWith('.pub');
|
|
const host = isPublicKey ? fileName.slice(0, -4) : fileName;
|
|
helpers.assertSafeHost(host);
|
|
|
|
this._hostVar = host;
|
|
if (isPublicKey) {
|
|
this._pubKey = plugins.fs.readFileSync(resolvedPath, 'utf8');
|
|
} else {
|
|
this._privKey = plugins.fs.readFileSync(resolvedPath, 'utf8');
|
|
}
|
|
}
|
|
|
|
static fromFile(filePathArg: string) {
|
|
const sshKey = new SshKey();
|
|
sshKey.read(filePathArg);
|
|
return sshKey;
|
|
}
|
|
|
|
static fromFiles(optionsArg: { privateKeyPath?: string; publicKeyPath?: string; host?: string }) {
|
|
const sshKey = new SshKey({ host: optionsArg.host });
|
|
if (optionsArg.privateKeyPath) {
|
|
sshKey.privKey = plugins.fs.readFileSync(plugins.path.resolve(optionsArg.privateKeyPath), 'utf8');
|
|
if (!sshKey.host) {
|
|
const fileName = plugins.path.basename(optionsArg.privateKeyPath);
|
|
helpers.assertSafeHost(fileName);
|
|
sshKey.host = fileName;
|
|
}
|
|
}
|
|
if (optionsArg.publicKeyPath) {
|
|
sshKey.pubKey = plugins.fs.readFileSync(plugins.path.resolve(optionsArg.publicKeyPath), 'utf8');
|
|
if (!sshKey.host) {
|
|
const fileName = plugins.path.basename(optionsArg.publicKeyPath).replace(/\.pub$/, '');
|
|
helpers.assertSafeHost(fileName);
|
|
sshKey.host = fileName;
|
|
}
|
|
}
|
|
return sshKey;
|
|
}
|
|
|
|
async store(dirPathArg: string) {
|
|
this.storeSync(dirPathArg);
|
|
}
|
|
|
|
storeSync(dirPathArg: string) {
|
|
helpers.assertSafeHost(this.host);
|
|
const resolvedDir = helpers.resolveSshDirPath(dirPathArg);
|
|
helpers.ensureSshDirSync(resolvedDir);
|
|
const fileNameBase = this.host;
|
|
if (this._privKey) {
|
|
const filePath = plugins.path.join(resolvedDir, fileNameBase);
|
|
plugins.fs.writeFileSync(filePath, this._privKey);
|
|
plugins.fs.chmodSync(filePath, 0o600);
|
|
}
|
|
if (this._pubKey) {
|
|
const filePath = plugins.path.join(resolvedDir, fileNameBase + '.pub');
|
|
plugins.fs.writeFileSync(filePath, this._pubKey);
|
|
plugins.fs.chmodSync(filePath, 0o644);
|
|
}
|
|
}
|
|
}
|