12 Commits

Author SHA1 Message Date
f0b52c8da7 1.2.4 2019-07-17 11:48:31 +02:00
4cb6aa03e6 fix(core): update 2019-07-17 11:48:31 +02:00
8b85b6c8bc 1.2.3 2018-09-17 22:32:31 +02:00
c032ff69d0 fix(core): update 2018-09-17 22:32:31 +02:00
0454eef45f update structure 2017-06-15 19:25:12 +02:00
def368f8ab 1.2.2 2017-06-15 17:53:24 +02:00
6853fa28b6 update to latest standards 2017-06-15 17:52:22 +02:00
56318f28cf 1.2.1 2016-11-23 12:44:37 +01:00
32b26f21cd improve README 2016-11-23 12:44:31 +01:00
32c2698af7 1.2.0 2016-11-23 12:38:45 +01:00
27237f14c7 update to latest standards 2016-11-23 12:38:38 +01:00
8f29f234f1 introducde more flexible pathing 2016-06-28 02:10:51 +02:00
44 changed files with 2842 additions and 969 deletions

28
.gitignore vendored
View File

@ -1,8 +1,22 @@
.idea/ .nogit/
node_modules/
# artifacts
coverage/ coverage/
docs/ public/
ts/typings/ pages/
ts/*.js
ts/*.js.map # installs
test/temp/ node_modules/
# caches
.yarn/
.cache/
.rpt2_cache
# builds
dist/
dist_web/
dist_serve/
dist_ts_web/
# custom

View File

@ -1,38 +1,117 @@
image: hosttoday/ht-docker-node:npmts # gitzone ci_default
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: "$CI_BUILD_STAGE"
stages: stages:
- security
- test - test
- release - release
- page - metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci npm prepare
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
testLTS: testLTS:
stage: test stage: test
script: script:
- npmci test lts - npmci npm prepare
- npmci node install lts
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - docker
- lossless - notpriv
testSTABLE: testBuild:
stage: test stage: test
script: script:
- npmci test stable - npmci npm prepare
- npmci node install lts
- npmci npm install
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - docker
- lossless - notpriv
testLEGACY:
stage: test
script:
- npmci test legacy
allow_failure: true
release: release:
stage: release stage: release
script: script:
- npmci publish - npmci node install lts
- npmci npm publish
only: only:
- tags - tags
tags:
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
allow_failure: true
script:
- npmci command npm install -g tslint typescript
- npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags:
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- docker
- notpriv
pages:
image: hosttoday/ht-docker-node:npmci
stage: metadata
script:
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install
- npmci command tsdoc
tags: tags:
- docker - docker
- lossless - notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true

View File

@ -1,12 +0,0 @@
language: node_js
node_js:
- '4'
- stable
deploy:
provider: npm
email: npm@lossless.digital
api_key:
secure: xApCMlDyZcTOgq+iomxR2A/2aMBhhPpgEBxdFYqXDNC/AGkr+NQJhGt67W4840FMrSUFEDZNQhOS+t6gYMqxUHv+vJFc0cHskFSuLDnAH2MS45TqtFYNcP+GARs1suuM9Il5hXNEvjVJ6XF0lYlNlK8mJstKQscdEKWyBHj42oSsgWRcuzBgqps8Vnbp+Ey2Bpfaw1yV+P1fyv8dNnkwG5dSt3EIxAcbGiMOhCz0u6oMroKfAYfNTxMJjja2uJJOqoTTShzeMyIYx+YwxorcZGfchI+TOPHHeVc+fByCHfzTZJYCy9qTSSTvWcKD/H7q3RGciEXHzhwMj0d8dlY3WPHC6BBliD6bLwVgDmToD3cdHm8OLsxW7hjFLO51vOIbhJZrWBVztlusuLwuyVAlIgeAsV8Yb5FxetxZmBU42qr5itykPl45rNd7talI0ZcoFPRTAWxxmCD8hp0d3ZLdjcEdbCzc5GYmEFN0NwKLTZF3Q1G4UbsHMgN8Pe4ohjdaYYhJ7RKgbmLR0J4NBrWIAUOhDaUTkZhgsHFyEmtbKI6JkxQtwCEBBBursemZWFQSIdtj2+O/RBaBCgoUNIpxUDBFq+D3Pir7BZP7DK2m3Otl0F9aCdqJmhCc7rOn3MueLpmndjtO1RFteXAdAkDxKp2RehIB6yohxbRmQ1O9PsA=
on:
tags: true
repo: pushrocks/smartssh

View File

@ -1,5 +0,0 @@
FROM hosttoday/ht-docker-node:npmts
COPY ./ /node-app
WORKDIR /node-app
RUN npm install
RUN npmts

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016 Push.Rocks Copyright (c) 2016 Lossless GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,34 +1,56 @@
# smartssh # @pushrocks/smartssh
setups SSH quickly and in a painless manner setups SSH quickly and in a painless manner
> Attention: This is still alpha, so some things won't work, not all things are inplemented. ## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartssh)
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartssh)
* [github.com (source mirror)](https://github.com/pushrocks/smartssh)
* [docs (typedoc)](https://pushrocks.gitlab.io/smartssh/)
## Status for master
[![build status](https://gitlab.com/pushrocks/smartssh/badges/master/build.svg)](https://gitlab.com/pushrocks/smartssh/commits/master)
[![coverage report](https://gitlab.com/pushrocks/smartssh/badges/master/coverage.svg)](https://gitlab.com/pushrocks/smartssh/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/@pushrocks/smartssh.svg)](https://www.npmjs.com/package/@pushrocks/smartssh)
[![Known Vulnerabilities](https://snyk.io/test/npm/@pushrocks/smartssh/badge.svg)](https://snyk.io/test/npm/@pushrocks/smartssh)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
## Usage ## Usage
```javascript ```javascript
var smartssh = require("smartssh"); var smartssh = require('smartssh');
var sshInstance = new smartssh.sshInstance({ var sshInstance = new smartssh.sshInstance({
sshDir: "/some/path/.ssh", // the standard ssh directory, optional, defaults to "~./.ssh" sshDir: '/some/path/.ssh', // the standard ssh directory, optional, defaults to "~./.ssh"
sshSync: true // sync ssh this instance will represent the status of an ssh dir if set to true; sshSync: true // sync ssh this instance will represent the status of an ssh dir if set to true;
}); });
sshInstance.addKey(new smartssh.sshKey({ sshInstance.addKey(
private: "somestring", new smartssh.sshKey({
public: "somestring", // optional private: 'somestring',
host:"github.com", public: 'somestring', // optional
encoding: "base64" // optional, defaults to "utf8", can be "utf8" or "base64", useful for reading ssh keys from environment variables host: 'github.com',
})); encoding: 'base64' // optional, defaults to "utf8", can be "utf8" or "base64", useful for reading ssh keys from environment variables
})
);
sshInstance.removeKey(sshInstance.getKey("github.com")); // removes key for host "github.com" is present sshInstance.removeKey(sshInstance.getKey('github.com')); // removes key for host "github.com" is present
sshInstance.createKey({ sshInstance.createKey({
host:"gitlab.com" // returns new key in the form sshKey, read more about the sshKey class below host: 'gitlab.com' // returns new key in the form sshKey, read more about the sshKey class below
})
sshInstance.getKey({ // returns ssh key in the form sshKey, read more about the sshKey class below
host:"github.com"
}); });
sshInstance.getKeys() // returns array of all available getKeys. Each key is in form of class sshKey sshInstance.getKey({
// returns ssh key in the form sshKey, read more about the sshKey class below
host: 'github.com'
});
sshInstance.getKeys(); // returns array of all available getKeys. Each key is in form of class sshKey
``` ```
For further information read the linked docs at the top of this readme.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://maintainedby.lossless.com)

5
dist/index.d.ts vendored
View File

@ -1,5 +0,0 @@
import "typings-global";
export { SshInstance } from "./smartssh.classes.sshinstance";
export { SshKey } from "./smartssh.classes.sshkey";
export { SshDir } from "./smartssh.classes.sshdir";
export { SshConfig } from "./smartssh.classes.sshconfig";

12
dist/index.js vendored
View File

@ -1,12 +0,0 @@
"use strict";
require("typings-global");
var smartssh_classes_sshinstance_1 = require("./smartssh.classes.sshinstance");
exports.SshInstance = smartssh_classes_sshinstance_1.SshInstance;
var smartssh_classes_sshkey_1 = require("./smartssh.classes.sshkey");
exports.SshKey = smartssh_classes_sshkey_1.SshKey;
var smartssh_classes_sshdir_1 = require("./smartssh.classes.sshdir");
exports.SshDir = smartssh_classes_sshdir_1.SshDir;
var smartssh_classes_sshconfig_1 = require("./smartssh.classes.sshconfig");
exports.SshConfig = smartssh_classes_sshconfig_1.SshConfig;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUNQLENBQUMsQ0FEc0I7QUFHdkIsNkNBQTBCLGdDQUFnQyxDQUFDO0FBQW5ELGlFQUFtRDtBQUMzRCx3Q0FBcUIsMkJBQTJCLENBQUM7QUFBekMsa0RBQXlDO0FBQ2pELHdDQUFxQiwyQkFBMkIsQ0FBQztBQUF6QyxrREFBeUM7QUFDakQsMkNBQXdCLDhCQUE4QixDQUFDO0FBQS9DLDJEQUErQyIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBcInR5cGluZ3MtZ2xvYmFsXCJcbmltcG9ydCAqIGFzIHBsdWdpbnMgZnJvbSBcIi4vc21hcnRzc2gucGx1Z2luc1wiO1xuXG5leHBvcnQge1NzaEluc3RhbmNlfSBmcm9tIFwiLi9zbWFydHNzaC5jbGFzc2VzLnNzaGluc3RhbmNlXCI7XG5leHBvcnQge1NzaEtleX0gZnJvbSBcIi4vc21hcnRzc2guY2xhc3Nlcy5zc2hrZXlcIjtcbmV4cG9ydCB7U3NoRGlyfSBmcm9tIFwiLi9zbWFydHNzaC5jbGFzc2VzLnNzaGRpclwiO1xuZXhwb3J0IHtTc2hDb25maWd9IGZyb20gXCIuL3NtYXJ0c3NoLmNsYXNzZXMuc3NoY29uZmlnXCI7Il19

View File

@ -1,3 +0,0 @@
import "typings-global";
import { SshKey } from "./smartssh.classes.sshkey";
export declare let sshKeyArrayFromDir: (dirArg: string) => SshKey[];

View File

@ -1,8 +0,0 @@
"use strict";
require("typings-global");
exports.sshKeyArrayFromDir = function (dirArg) {
var sshKeyArray = []; //TODO
return sshKeyArray;
};
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLmNsYXNzZXMuaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsUUFBTyxnQkFDUCxDQUFDLENBRHNCO0FBSVosMEJBQWtCLEdBQUcsVUFBUyxNQUFhO0lBQ2xELElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQyxDQUFDLE1BQU07SUFDNUIsTUFBTSxDQUFDLFdBQVcsQ0FBQztBQUN2QixDQUFDLENBQUEiLCJmaWxlIjoic21hcnRzc2guY2xhc3Nlcy5oZWxwZXJzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIlxuaW1wb3J0ICogYXMgcGx1Z2lucyBmcm9tIFwiLi9zbWFydHNzaC5wbHVnaW5zXCI7XG5pbXBvcnQge1NzaEtleX0gZnJvbSBcIi4vc21hcnRzc2guY2xhc3Nlcy5zc2hrZXlcIjtcblxuZXhwb3J0IGxldCBzc2hLZXlBcnJheUZyb21EaXIgPSBmdW5jdGlvbihkaXJBcmc6c3RyaW5nKTpTc2hLZXlbXXtcbiAgICBsZXQgc3NoS2V5QXJyYXkgPSBbXTsgLy9UT0RPXG4gICAgcmV0dXJuIHNzaEtleUFycmF5O1xufSJdfQ==

View File

@ -1,16 +0,0 @@
import "typings-global";
import { SshKey } from "./smartssh.classes.sshkey";
export declare class SshConfig {
sshKeyArray: SshKey[];
constructor(sshKeyArrayArg: SshKey[]);
/**
* stores a config file
*/
store(dirPathArg: string): any;
read(dirPathArg: any): any;
}
export interface configObject {
configString: string;
authorized: boolean;
sshKey: SshKey;
}

View File

@ -1,48 +0,0 @@
"use strict";
require("typings-global");
var plugins = require("./smartssh.plugins");
var SshConfig = (function () {
function SshConfig(sshKeyArrayArg) {
this.sshKeyArray = sshKeyArrayArg;
}
/**
* stores a config file
*/
SshConfig.prototype.store = function (dirPathArg) {
var done = plugins.q.defer();
var configArray = [];
var configString;
for (var key in this.sshKeyArray) {
var sshKey = this.sshKeyArray[key];
if (sshKey.host) {
configString = "Host " + sshKey.host + "\n" +
" HostName " + sshKey.host + "\n" +
" IdentityFile ~/.ssh/" + sshKey.host + "\n" +
" StrictHostKeyChecking no" + "\n";
}
configArray.push({
configString: configString,
authorized: sshKey.authorized,
sshKey: sshKey
});
}
var configFile = "";
for (var key in configArray) {
configFile = configFile + configArray[key].configString + "\n";
}
;
plugins.smartfile.memory.toFsSync(configFile, plugins.path.join(dirPathArg, "config"));
return done.promise;
};
SshConfig.prototype.read = function (dirPathArg) {
var done = plugins.q.defer();
var configArray;
return done.promise;
};
return SshConfig;
}());
exports.SshConfig = SshConfig;
;
;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLmNsYXNzZXMuc3NoY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUFnQixDQUFDLENBQUE7QUFDeEIsSUFBWSxPQUFPLFdBQU0sb0JBQW9CLENBQUMsQ0FBQTtBQUk5QztJQUVJLG1CQUFZLGNBQXVCO1FBQy9CLElBQUksQ0FBQyxXQUFXLEdBQUcsY0FBYyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7T0FFRztJQUNILHlCQUFLLEdBQUwsVUFBTSxVQUFpQjtRQUNuQixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzdCLElBQUksV0FBVyxHQUFrQixFQUFFLENBQUM7UUFDcEMsSUFBSSxZQUFZLENBQUM7UUFDakIsR0FBRyxDQUFBLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFBLENBQUM7WUFDN0IsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNuQyxFQUFFLENBQUEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUEsQ0FBQztnQkFDWixZQUFZLEdBQUcsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSTtvQkFDeEIsYUFBYSxHQUFHLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSTtvQkFDbEMsd0JBQXdCLEdBQUcsTUFBTSxDQUFDLElBQUksR0FBRyxJQUFJO29CQUM3Qyw0QkFBNEIsR0FBRyxJQUFJLENBQUE7WUFDMUQsQ0FBQztZQUNELFdBQVcsQ0FBQyxJQUFJLENBQUM7Z0JBQ2IsWUFBWSxFQUFDLFlBQVk7Z0JBQ3pCLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtnQkFDN0IsTUFBTSxFQUFFLE1BQU07YUFDakIsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztRQUNELElBQUksVUFBVSxHQUFVLEVBQUUsQ0FBQztRQUMzQixHQUFHLENBQUEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxXQUFXLENBQUMsQ0FBQSxDQUFDO1lBQ3hCLFVBQVUsR0FBRyxVQUFVLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDbkUsQ0FBQztRQUFBLENBQUM7UUFDRixPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ3JGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3hCLENBQUM7SUFDRCx3QkFBSSxHQUFKLFVBQUssVUFBVTtRQUNYLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDN0IsSUFBSSxXQUEwQixDQUFDO1FBRS9CLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3hCLENBQUM7SUFDTCxnQkFBQztBQUFELENBeENBLEFBd0NDLElBQUE7QUF4Q1ksaUJBQVMsWUF3Q3JCLENBQUE7QUFBQSxDQUFDO0FBTUQsQ0FBQyIsImZpbGUiOiJzbWFydHNzaC5jbGFzc2VzLnNzaGNvbmZpZy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBcInR5cGluZ3MtZ2xvYmFsXCI7XG5pbXBvcnQgKiBhcyBwbHVnaW5zIGZyb20gXCIuL3NtYXJ0c3NoLnBsdWdpbnNcIjtcbmltcG9ydCAqIGFzIGhlbHBlcnMgZnJvbSBcIi4vc21hcnRzc2guY2xhc3Nlcy5oZWxwZXJzXCI7XG5pbXBvcnQge1NzaEtleX0gZnJvbSBcIi4vc21hcnRzc2guY2xhc3Nlcy5zc2hrZXlcIlxuXG5leHBvcnQgY2xhc3MgU3NoQ29uZmlnIHtcbiAgICBzc2hLZXlBcnJheTpTc2hLZXlbXTtcbiAgICBjb25zdHJ1Y3Rvcihzc2hLZXlBcnJheUFyZzpTc2hLZXlbXSl7XG4gICAgICAgIHRoaXMuc3NoS2V5QXJyYXkgPSBzc2hLZXlBcnJheUFyZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBzdG9yZXMgYSBjb25maWcgZmlsZVxuICAgICAqL1xuICAgIHN0b3JlKGRpclBhdGhBcmc6c3RyaW5nKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgbGV0IGNvbmZpZ0FycmF5OmNvbmZpZ09iamVjdFtdID0gW107XG4gICAgICAgIGxldCBjb25maWdTdHJpbmc7XG4gICAgICAgIGZvcihsZXQga2V5IGluIHRoaXMuc3NoS2V5QXJyYXkpe1xuICAgICAgICAgICAgbGV0IHNzaEtleSA9IHRoaXMuc3NoS2V5QXJyYXlba2V5XTtcbiAgICAgICAgICAgIGlmKHNzaEtleS5ob3N0KXtcbiAgICAgICAgICAgICAgICBjb25maWdTdHJpbmcgPSBcIkhvc3QgXCIgKyBzc2hLZXkuaG9zdCArIFwiXFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIiAgSG9zdE5hbWUgXCIgKyBzc2hLZXkuaG9zdCArIFwiXFxuXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIiAgSWRlbnRpdHlGaWxlIH4vLnNzaC9cIiArIHNzaEtleS5ob3N0ICsgXCJcXG5cIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiICBTdHJpY3RIb3N0S2V5Q2hlY2tpbmcgbm9cIiArIFwiXFxuXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbmZpZ0FycmF5LnB1c2goe1xuICAgICAgICAgICAgICAgIGNvbmZpZ1N0cmluZzpjb25maWdTdHJpbmcsXG4gICAgICAgICAgICAgICAgYXV0aG9yaXplZDogc3NoS2V5LmF1dGhvcml6ZWQsXG4gICAgICAgICAgICAgICAgc3NoS2V5OiBzc2hLZXlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGxldCBjb25maWdGaWxlOnN0cmluZyA9IFwiXCI7XG4gICAgICAgIGZvcihsZXQga2V5IGluIGNvbmZpZ0FycmF5KXtcbiAgICAgICAgICAgIGNvbmZpZ0ZpbGUgPSBjb25maWdGaWxlICsgY29uZmlnQXJyYXlba2V5XS5jb25maWdTdHJpbmcgKyBcIlxcblwiO1xuICAgICAgICB9O1xuICAgICAgICBwbHVnaW5zLnNtYXJ0ZmlsZS5tZW1vcnkudG9Gc1N5bmMoY29uZmlnRmlsZSxwbHVnaW5zLnBhdGguam9pbihkaXJQYXRoQXJnLFwiY29uZmlnXCIpKTtcbiAgICAgICAgcmV0dXJuIGRvbmUucHJvbWlzZTtcbiAgICB9XG4gICAgcmVhZChkaXJQYXRoQXJnKXtcbiAgICAgICAgbGV0IGRvbmUgPSBwbHVnaW5zLnEuZGVmZXIoKTtcbiAgICAgICAgbGV0IGNvbmZpZ0FycmF5OmNvbmZpZ09iamVjdFtdO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIGRvbmUucHJvbWlzZTtcbiAgICB9XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIGNvbmZpZ09iamVjdCB7XG4gICAgY29uZmlnU3RyaW5nOnN0cmluZztcbiAgICBhdXRob3JpemVkOmJvb2xlYW47XG4gICAgc3NoS2V5OlNzaEtleTtcbn07XG5cbiJdfQ==

View File

@ -1,13 +0,0 @@
import "typings-global";
import { SshKey } from "./smartssh.classes.sshkey";
import { SshConfig } from "./smartssh.classes.sshconfig";
export declare class SshDir {
private _path;
private _sshKeyArray;
private _sshConfig;
constructor(sshKeyArray: SshKey[], sshConfig: SshConfig, sshDirPathArg?: string);
writeToDir(): void;
readFromDir(): void;
updateDirPath(dirPathArg: string): void;
getKeys(): SshKey[];
}

View File

@ -1,38 +0,0 @@
"use strict";
require("typings-global");
var plugins = require("./smartssh.plugins");
var helpers = require("./smartssh.classes.helpers");
var SshDir = (function () {
function SshDir(sshKeyArray, sshConfig, sshDirPathArg) {
this._sshKeyArray = sshKeyArray;
this._sshConfig = sshConfig;
if (sshDirPathArg) {
this._path = sshDirPathArg;
}
else {
this._path = plugins.path.join(plugins.smartpath.get.home(), ".ssh/");
}
;
}
SshDir.prototype.writeToDir = function () {
var _this = this;
this._sshKeyArray.forEach(function (sshKeyArg) {
sshKeyArg.store(_this._path);
});
this._sshConfig.store(this._path);
};
;
SshDir.prototype.readFromDir = function () {
};
SshDir.prototype.updateDirPath = function (dirPathArg) {
this._path = dirPathArg;
};
;
SshDir.prototype.getKeys = function () {
return helpers.sshKeyArrayFromDir(this._path);
};
return SshDir;
}());
exports.SshDir = SshDir;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLmNsYXNzZXMuc3NoZGlyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUFnQixDQUFDLENBQUE7QUFDeEIsSUFBWSxPQUFPLFdBQU0sb0JBQW9CLENBQUMsQ0FBQTtBQUM5QyxJQUFZLE9BQU8sV0FBTSw0QkFBNEIsQ0FBQyxDQUFBO0FBSXREO0lBSUksZ0JBQVksV0FBb0IsRUFBQyxTQUFtQixFQUFDLGFBQXFCO1FBQ3RFLElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO1FBQzVCLEVBQUUsQ0FBQSxDQUFDLGFBQWEsQ0FBQyxDQUFBLENBQUM7WUFDZCxJQUFJLENBQUMsS0FBSyxHQUFHLGFBQWEsQ0FBQztRQUMvQixDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDSixJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3pFLENBQUM7UUFBQSxDQUFDO0lBQ04sQ0FBQztJQUNELDJCQUFVLEdBQVY7UUFBQSxpQkFLQztRQUpHLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFVBQUMsU0FBUztZQUNoQyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0QyxDQUFDOztJQUNELDRCQUFXLEdBQVg7SUFFQSxDQUFDO0lBQ0QsOEJBQWEsR0FBYixVQUFjLFVBQWlCO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDO0lBQzVCLENBQUM7O0lBQ0Qsd0JBQU8sR0FBUDtRQUNJLE1BQU0sQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFDTCxhQUFDO0FBQUQsQ0E1QkEsQUE0QkMsSUFBQTtBQTVCWSxjQUFNLFNBNEJsQixDQUFBIiwiZmlsZSI6InNtYXJ0c3NoLmNsYXNzZXMuc3NoZGlyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIjtcbmltcG9ydCAqIGFzIHBsdWdpbnMgZnJvbSBcIi4vc21hcnRzc2gucGx1Z2luc1wiO1xuaW1wb3J0ICogYXMgaGVscGVycyBmcm9tIFwiLi9zbWFydHNzaC5jbGFzc2VzLmhlbHBlcnNcIjtcbmltcG9ydCB7U3NoSW5zdGFuY2V9IGZyb20gXCIuL3NtYXJ0c3NoLmNsYXNzZXMuc3NoaW5zdGFuY2VcIjtcbmltcG9ydCB7U3NoS2V5fSBmcm9tIFwiLi9zbWFydHNzaC5jbGFzc2VzLnNzaGtleVwiO1xuaW1wb3J0IHtTc2hDb25maWd9IGZyb20gXCIuL3NtYXJ0c3NoLmNsYXNzZXMuc3NoY29uZmlnXCI7XG5leHBvcnQgY2xhc3MgU3NoRGlyIHsgLy8gc3NoRGlyIGNsYXNzIC0+IE5PVCBFWFBPUlRFRCwgT05MWSBGT1IgSU5URVJOQUwgVVNFXG4gICAgcHJpdmF0ZSBfcGF0aDpzdHJpbmc7IC8vIHRoZSBwYXRoIG9mIHRoZSBzc2ggZGlyZWN0b3J5XG4gICAgcHJpdmF0ZSBfc3NoS2V5QXJyYXk6U3NoS2V5W107XG4gICAgcHJpdmF0ZSBfc3NoQ29uZmlnOlNzaENvbmZpZztcbiAgICBjb25zdHJ1Y3Rvcihzc2hLZXlBcnJheTpTc2hLZXlbXSxzc2hDb25maWc6U3NoQ29uZmlnLHNzaERpclBhdGhBcmc/OnN0cmluZyl7XG4gICAgICAgIHRoaXMuX3NzaEtleUFycmF5ID0gc3NoS2V5QXJyYXk7XG4gICAgICAgIHRoaXMuX3NzaENvbmZpZyA9IHNzaENvbmZpZztcbiAgICAgICAgaWYoc3NoRGlyUGF0aEFyZyl7XG4gICAgICAgICAgICB0aGlzLl9wYXRoID0gc3NoRGlyUGF0aEFyZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3BhdGggPSBwbHVnaW5zLnBhdGguam9pbihwbHVnaW5zLnNtYXJ0cGF0aC5nZXQuaG9tZSgpLFwiLnNzaC9cIik7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHdyaXRlVG9EaXIoKXsgLy8gc3luY3Mgc3NoSW5zdGFuY2UgdG8gZGlyZWN0b3J5XG4gICAgICAgIHRoaXMuX3NzaEtleUFycmF5LmZvckVhY2goKHNzaEtleUFyZykgPT4ge1xuICAgICAgICAgICAgc3NoS2V5QXJnLnN0b3JlKHRoaXMuX3BhdGgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc3NoQ29uZmlnLnN0b3JlKHRoaXMuX3BhdGgpO1xuICAgIH07XG4gICAgcmVhZEZyb21EaXIoKXsgLy8gc3luY3Mgc3NoSW5zdGFuY2UgZnJvbSBkaXJlY3RvcnlcbiAgICAgICAgXG4gICAgfVxuICAgIHVwZGF0ZURpclBhdGgoZGlyUGF0aEFyZzpzdHJpbmcpe1xuICAgICAgICB0aGlzLl9wYXRoID0gZGlyUGF0aEFyZztcbiAgICB9O1xuICAgIGdldEtleXMoKXtcbiAgICAgICAgcmV0dXJuIGhlbHBlcnMuc3NoS2V5QXJyYXlGcm9tRGlyKHRoaXMuX3BhdGgpO1xuICAgIH1cbn0iXX0=

View File

@ -1,34 +0,0 @@
import "typings-global";
import { SshKey } from "./smartssh.classes.sshkey";
export declare class SshInstance {
private _sshKeyArray;
private _sshConfig;
private _sshDir;
private _sshSync;
constructor(optionsArg?: {
sshDirPath?: string;
sshSync?: boolean;
});
addKey(sshKeyArg: SshKey): void;
removeKey(sshKeyArg: SshKey): void;
replaceKey(sshKeyOldArg: SshKey, sshKeyNewArg: SshKey): void;
getKey(hostArg: string): SshKey;
sshKeys: SshKey[];
/**
* write SshInstance to disk
*/
writeToDisk(): void;
/**
* read ab SshInstance from disk
*/
readFromDisk(): void;
private _makeConfig();
/**
* method to invoke SshInstance _sync automatically when sshSync is true
*/
private _syncAuto(directionArg);
/**
* private method to sync SshInstance
*/
private _sync(directionArg);
}

File diff suppressed because one or more lines are too long

View File

@ -1,22 +0,0 @@
import "typings-global";
export declare class SshKey {
private _privKey;
private _pubKey;
private _hostVar;
private _authorized;
constructor(optionsArg?: {
private?: string;
public?: string;
host?: string;
authorized?: boolean;
});
host: string;
privKey: string;
privKeyBase64: string;
pubKey: string;
pubKeyBase64: string;
authorized: boolean;
type: any;
read(filePathArg: any): void;
store(dirPathArg: string): void;
}

File diff suppressed because one or more lines are too long

View File

@ -1,10 +0,0 @@
import "typings-global";
export import beautylog = require("beautylog");
export declare let base64: any;
export declare let fs: any;
export declare let minimatch: any;
export import path = require("path");
export declare let q: any;
export declare let shelljs: any;
export import smartfile = require("smartfile");
export import smartpath = require("smartpath");

View File

@ -1,13 +0,0 @@
"use strict";
require("typings-global");
exports.beautylog = require("beautylog");
exports.base64 = require("js-base64").Base64;
exports.fs = require("fs-extra");
exports.minimatch = require("minimatch");
exports.path = require("path");
exports.q = require("q");
exports.shelljs = require("shelljs");
exports.smartfile = require("smartfile");
exports.smartpath = require("smartpath");
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sZ0JBQ1AsQ0FBQyxDQURzQjtBQUNULGlCQUFTLFdBQVcsV0FBVyxDQUFDLENBQUM7QUFDcEMsY0FBTSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDckMsVUFBRSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUN6QixpQkFBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUM5QixZQUFJLFdBQVcsTUFBTSxDQUFDLENBQUM7QUFDMUIsU0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixlQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzFCLGlCQUFTLFdBQVcsV0FBVyxDQUFDLENBQUM7QUFDakMsaUJBQVMsV0FBVyxXQUFXLENBQUMsQ0FBQyIsImZpbGUiOiJzbWFydHNzaC5wbHVnaW5zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIlxuZXhwb3J0IGltcG9ydCBiZWF1dHlsb2cgPSByZXF1aXJlKFwiYmVhdXR5bG9nXCIpO1xuZXhwb3J0IGxldCBiYXNlNjQgPSByZXF1aXJlKFwianMtYmFzZTY0XCIpLkJhc2U2NDtcbmV4cG9ydCBsZXQgZnMgPSByZXF1aXJlKFwiZnMtZXh0cmFcIik7XG5leHBvcnQgbGV0IG1pbmltYXRjaCA9IHJlcXVpcmUoXCJtaW5pbWF0Y2hcIik7XG5leHBvcnQgaW1wb3J0IHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcbmV4cG9ydCBsZXQgcSA9IHJlcXVpcmUoXCJxXCIpO1xuZXhwb3J0IGxldCBzaGVsbGpzID0gcmVxdWlyZShcInNoZWxsanNcIik7XG5leHBvcnQgaW1wb3J0IHNtYXJ0ZmlsZSA9IHJlcXVpcmUoXCJzbWFydGZpbGVcIik7XG5leHBvcnQgaW1wb3J0IHNtYXJ0cGF0aCA9IHJlcXVpcmUoXCJzbWFydHBhdGhcIik7Il19

16
npmextra.json Normal file
View File

@ -0,0 +1,16 @@
{
"npmci": {
"npmGlobalTools": [],
"npmAccessLevel": "public"
},
"gitzone": {
"module": {
"githost": "gitlab.com",
"gitscope": "pushrocks",
"gitrepo": "smartssh",
"shortDescription": "setups SSH quickly and in a painless manner",
"npmPackagename": "@pushrocks/smartssh",
"license": "MIT"
}
}
}

View File

@ -1,4 +0,0 @@
{
"mode":"default",
"coverageTreshold":50
}

2204
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,14 @@
{ {
"name": "smartssh", "name": "@pushrocks/smartssh",
"version": "1.1.5", "version": "1.2.4",
"private": false,
"description": "setups SSH quickly and in a painless manner", "description": "setups SSH quickly and in a painless manner",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
"scripts": { "scripts": {
"test": "(npmts)" "test": "(tstest test/)",
"testDocker": "tsdocker",
"build": "(tsbuild)"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -23,19 +26,32 @@
}, },
"homepage": "https://gitlab.com/pushrocks/smartssh#readme", "homepage": "https://gitlab.com/pushrocks/smartssh#readme",
"dependencies": { "dependencies": {
"beautylog": "^5.0.12", "@pushrocks/smartfile": "^7.0.4",
"fs-extra": "^0.30.0", "@pushrocks/smartpath": "^4.0.1",
"js-base64": "^2.1.9", "@pushrocks/smartpromise": "^3.0.2",
"minimatch": "^3.0.2", "@pushrocks/smartshell": "^2.0.23",
"q": "^1.4.1", "@pushrocks/smartstring": "^3.0.10",
"shelljs": "^0.7.0", "@types/fs-extra": "^8.0.0",
"smartfile": "^4.0.5", "@types/minimatch": "^3.0.3",
"smartpath": "^3.2.2", "fs-extra": "^8.1.0",
"typings-global": "^1.0.3", "minimatch": "^3.0.4"
"typings-test": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
"npmts-g": "^5.2.6", "@gitzone/tsbuild": "^2.1.11",
"should": "^9.0.2" "@gitzone/tsdocker": "^1.2.39",
} "@gitzone/tsrun": "^1.2.6",
"@gitzone/tstest": "^1.0.24",
"@pushrocks/tapbundle": "^3.0.11",
"@types/node": "^12.6.6"
},
"files": [
"ts/*",
"ts_web/*",
"dist/*",
"dist_web/*",
"assets/*",
"cli.js",
"npmextra.json",
"readme.md"
]
} }

1
test/temp/bitbucket.org Normal file
View File

@ -0,0 +1 @@
somePrivateKey

View File

@ -0,0 +1 @@
somePublicKey

15
test/temp/config Normal file
View File

@ -0,0 +1,15 @@
Host gitlab.com
HostName gitlab.com
IdentityFile ~/.ssh/gitlab.com
StrictHostKeyChecking no
Host bitbucket.org
HostName bitbucket.org
IdentityFile ~/.ssh/bitbucket.org
StrictHostKeyChecking no
Host github.com
HostName github.com
IdentityFile ~/.ssh/github.com
StrictHostKeyChecking no

1
test/temp/example.com Normal file
View File

@ -0,0 +1 @@
someExamplePrivateKey

View File

@ -0,0 +1 @@
someExamplePublicKey

1
test/temp/github.com Normal file
View File

@ -0,0 +1 @@
someGitHubPrivateKey

1
test/temp/github.com.pub Normal file
View File

@ -0,0 +1 @@
someGitHubPublicKey

1
test/temp/gitlab.com Normal file
View File

@ -0,0 +1 @@
somePrivateKey

1
test/temp/gitlab.com.pub Normal file
View File

@ -0,0 +1 @@
somePublicKey

2
test/test.d.ts vendored
View File

@ -1,2 +0,0 @@
import "typings-test";
import "should";

File diff suppressed because one or more lines are too long

View File

@ -1,75 +1,84 @@
import "typings-test" import { expect, tap } from '@pushrocks/tapbundle';
import "should"; import smartssh = require('../ts/index');
import smartssh = require("../dist/index"); import path = require('path');
import path = require("path");
describe("smartssh",function(){ let testSshInstance: smartssh.SshInstance;
let testSshInstance:smartssh.SshInstance; let testSshKey: smartssh.SshKey;
let testSshKey:smartssh.SshKey; tap.test('should create a valid SshKey object', async () => {
describe(".SshKey",function(){ testSshKey = new smartssh.SshKey({
it("'new' keyword should create a valid SshKey object",function(){ host: 'example.com',
testSshKey = new smartssh.SshKey({ private: 'someExamplePrivateKey',
host:"example.com", public: 'someExamplePublicKey'
private:"someExamplePrivateKey", });
public:"someExamplePublicKey" expect(testSshKey).to.be.instanceof(smartssh.SshKey);
}); });
testSshKey.should.be.instanceof(smartssh.SshKey); tap.test('.type should be a valid type', async () => {
}); expect(testSshKey.type).equal('duplex');
it(".type should be a valid type",function(){ });
testSshKey.type.should.equal("duplex"); tap.test('.publicKey should be public key', async () => {
}); expect(testSshKey.pubKey).equal('someExamplePublicKey');
it(".publicKey should be public key",function(){ });
testSshKey.pubKey.should.equal("someExamplePublicKey"); tap.test('.privateKey should be private key', async () => {
}); expect(testSshKey.privKey).equal('someExamplePrivateKey');
it(".privateKey should be private key",function(){ });
testSshKey.privKey.should.equal("someExamplePrivateKey"); tap.test('.publicKeyBase64 should be public key base 64 encoded', async () => {
}); // tslint:disable-next-line:no-unused-expression
it(".publicKeyBase64 should be public key base 64 encoded",function(){ testSshKey.pubKeyBase64;
testSshKey.pubKeyBase64; });
}); tap.test('.store() should store the file to disk', async () => {
it(".store() should store the file to disk",function(){ testSshKey.store(path.join(process.cwd(), 'test/temp'));
testSshKey.store(path.join(process.cwd(),"test/temp")); });
});
}); // SSH INstance
describe(".SshInstance",function(){ tap.test("'new' keyword should create a new SshInstance object from class", async () => {
it("'new' keyword should create a new SshInstance object from class",function(){ testSshInstance = new smartssh.SshInstance({
testSshInstance = new smartssh.SshInstance({ sshDirPath: path.join(process.cwd(), 'test/temp/')
sshDirPath: path.join(process.cwd(),"test/temp/") });
}); expect(testSshInstance).be.instanceof(smartssh.SshInstance);
testSshInstance.should.be.instanceof(smartssh.SshInstance); });
}); tap.test('.addKey() should accept a new SshKey object', async () => {
it(".addKey() should accept a new SshKey object",function(){ testSshInstance.addKey(
testSshInstance.addKey(new smartssh.SshKey({ new smartssh.SshKey({
public:"somePublicKey", public: 'somePublicKey',
private:"somePrivateKey", private: 'somePrivateKey',
host:"gitlab.com" host: 'gitlab.com'
})); })
testSshInstance.addKey(new smartssh.SshKey({ );
public:"somePublicKey", testSshInstance.addKey(
private:"somePrivateKey", new smartssh.SshKey({
host:"bitbucket.org" public: 'somePublicKey',
})); private: 'somePrivateKey',
testSshInstance.addKey(new smartssh.SshKey({ host: 'bitbucket.org'
public:"someGitHubPublicKey", })
private:"someGitHubPrivateKey", );
host:"github.com" testSshInstance.addKey(
})); new smartssh.SshKey({
}); public: 'someGitHubPublicKey',
it(".sshKeys should point to an array of sshKeys",function(){ private: 'someGitHubPrivateKey',
let sshKeyArray = testSshInstance.sshKeys; host: 'github.com'
sshKeyArray.should.be.Array(); })
sshKeyArray[0].host.should.equal("gitlab.com"); );
sshKeyArray[1].host.should.equal("bitbucket.org"); });
sshKeyArray[2].host.should.equal("github.com");
}); tap.test('.sshKeys should point to an array of sshKeys', async () => {
it(".getKey() should get a specific key selected by host",function(){ let sshKeyArray = testSshInstance.sshKeys;
testSshInstance.getKey("github.com").pubKey.should.equal("someGitHubPublicKey"); expect(sshKeyArray).be.instanceOf(Array);
}) expect(sshKeyArray[0].host).equal('gitlab.com');
it(".removeKey() should remove a key",function(){ expect(sshKeyArray[1].host).equal('bitbucket.org');
testSshInstance.removeKey(testSshInstance.getKey("bitbucket.org")); expect(sshKeyArray[2].host).equal('github.com');
testSshInstance.sshKeys[1].host.should.equal("github.com"); });
});
it("it should store to disk",function(){ tap.test('.getKey() should get a specific key selected by host', async () => {
testSshInstance.writeToDisk(); expect(testSshInstance.getKey('github.com').pubKey).equal('someGitHubPublicKey');
}) });
});
}) tap.test('.removeKey() should remove a key', async () => {
testSshInstance.removeKey(testSshInstance.getKey('bitbucket.org'));
expect(testSshInstance.sshKeys[1].host).equal('github.com');
});
tap.test('it should store to disk', async () => {
testSshInstance.writeToDisk();
});
tap.start();

View File

@ -1,7 +1,6 @@
import "typings-global" import * as plugins from './smartssh.plugins';
import * as plugins from "./smartssh.plugins";
export {SshInstance} from "./smartssh.classes.sshinstance"; export { SshInstance } from './smartssh.classes.sshinstance';
export {SshKey} from "./smartssh.classes.sshkey"; export { SshKey } from './smartssh.classes.sshkey';
export {SshDir} from "./smartssh.classes.sshdir"; export { SshDir } from './smartssh.classes.sshdir';
export {SshConfig} from "./smartssh.classes.sshconfig"; export { SshConfig } from './smartssh.classes.sshconfig';

View File

@ -1,8 +1,7 @@
import "typings-global" import * as plugins from './smartssh.plugins';
import * as plugins from "./smartssh.plugins"; import { SshKey } from './smartssh.classes.sshkey';
import {SshKey} from "./smartssh.classes.sshkey";
export let sshKeyArrayFromDir = function(dirArg:string):SshKey[]{ export let sshKeyArrayFromDir = function(dirArg: string): SshKey[] {
let sshKeyArray = []; //TODO let sshKeyArray = []; // TODO
return sshKeyArray; return sshKeyArray;
} };

View File

@ -1,53 +1,60 @@
import "typings-global"; import * as plugins from './smartssh.plugins';
import * as plugins from "./smartssh.plugins"; import * as helpers from './smartssh.classes.helpers';
import * as helpers from "./smartssh.classes.helpers"; import { SshKey } from './smartssh.classes.sshkey';
import {SshKey} from "./smartssh.classes.sshkey"
export class SshConfig { export class SshConfig {
sshKeyArray:SshKey[]; private _sshKeyArray: SshKey[];
constructor(sshKeyArrayArg:SshKey[]){ constructor(sshKeyArrayArg: SshKey[]) {
this.sshKeyArray = sshKeyArrayArg; this._sshKeyArray = sshKeyArrayArg;
} }
/** /**
* stores a config file * stores a config file
*/ */
store(dirPathArg:string){ store(dirPathArg: string) {
let done = plugins.q.defer(); let done = plugins.smartpromise.defer();
let configArray:configObject[] = []; let configArray: configObject[] = [];
let configString; let configString;
for(let key in this.sshKeyArray){ for (let key in this._sshKeyArray) {
let sshKey = this.sshKeyArray[key]; let sshKey = this._sshKeyArray[key];
if(sshKey.host){ if (sshKey.host) {
configString = "Host " + sshKey.host + "\n" + configString =
" HostName " + sshKey.host + "\n" + 'Host ' +
" IdentityFile ~/.ssh/" + sshKey.host + "\n" + sshKey.host +
" StrictHostKeyChecking no" + "\n" '\n' +
} ' HostName ' +
configArray.push({ sshKey.host +
configString:configString, '\n' +
authorized: sshKey.authorized, ' IdentityFile ~/.ssh/' +
sshKey: sshKey sshKey.host +
}); '\n' +
} ' StrictHostKeyChecking no' +
let configFile:string = ""; '\n';
for(let key in configArray){ }
configFile = configFile + configArray[key].configString + "\n"; configArray.push({
}; configString: configString,
plugins.smartfile.memory.toFsSync(configFile,plugins.path.join(dirPathArg,"config")); authorized: sshKey.authorized,
return done.promise; sshKey: sshKey
});
} }
read(dirPathArg){ let configFile: string = '';
let done = plugins.q.defer(); for (let key in configArray) {
let configArray:configObject[]; configFile = configFile + configArray[key].configString + '\n';
}
plugins.smartfile.memory.toFsSync(configFile, plugins.path.join(dirPathArg, 'config'));
return done.promise;
}
read(dirPathArg) {
let done = plugins.smartpromise.defer();
let configArray: configObject[];
plugins.smartfile.fs.toStringSync(plugins.path.join(dirPathArg, 'config'));
return done.promise; return done.promise;
} }
}; }
export interface configObject { export interface configObject {
configString:string; configString: string;
authorized:boolean; authorized: boolean;
sshKey:SshKey; sshKey: SshKey;
}; }

View File

@ -1,35 +1,47 @@
import "typings-global"; import * as plugins from './smartssh.plugins';
import * as plugins from "./smartssh.plugins"; import * as helpers from './smartssh.classes.helpers';
import * as helpers from "./smartssh.classes.helpers"; import { SshInstance } from './smartssh.classes.sshinstance';
import {SshInstance} from "./smartssh.classes.sshinstance"; import { SshKey } from './smartssh.classes.sshkey';
import {SshKey} from "./smartssh.classes.sshkey"; import { SshConfig } from './smartssh.classes.sshconfig';
import {SshConfig} from "./smartssh.classes.sshconfig";
export class SshDir { // sshDir class -> NOT EXPORTED, ONLY FOR INTERNAL USE
private _path:string; // the path of the ssh directory
private _sshKeyArray:SshKey[];
private _sshConfig:SshConfig;
constructor(sshKeyArray:SshKey[],sshConfig:SshConfig,sshDirPathArg?:string){
this._sshKeyArray = sshKeyArray;
this._sshConfig = sshConfig;
if(sshDirPathArg){
this._path = sshDirPathArg;
} else {
this._path = plugins.path.join(plugins.smartpath.get.home(),".ssh/");
};
}
writeToDir(){ // syncs sshInstance to directory
this._sshKeyArray.forEach((sshKeyArg) => {
sshKeyArg.store(this._path);
});
this._sshConfig.store(this._path);
};
readFromDir(){ // syncs sshInstance from directory
export class SshDir {
// sshDir class -> NOT EXPORTED, ONLY FOR INTERNAL USE
private _path: string; // the path of the ssh directory
private _sshKeyArray: SshKey[];
private _sshConfig: SshConfig;
constructor(sshKeyArray: SshKey[], sshConfig: SshConfig, sshDirPathArg?: string) {
this._sshKeyArray = sshKeyArray;
this._sshConfig = sshConfig;
if (sshDirPathArg) {
this._path = sshDirPathArg;
} else {
this._path = plugins.path.join(plugins.smartpath.get.home(), '.ssh/');
} }
updateDirPath(dirPathArg:string){ }
this._path = dirPathArg;
}; writeToDir(dirPathArg?: string) {
getKeys(){ // syncs sshInstance to directory
return helpers.sshKeyArrayFromDir(this._path); let path = this._path;
} if (dirPathArg) path = dirPathArg;
this._sshKeyArray.forEach(sshKeyArg => {
sshKeyArg.store(path);
});
this._sshConfig.store(path);
}
/**
* TODO: implement reading of directories
*/
readFromDir(dirPathArg?: string) {
// syncs sshInstance from directory
let path = this._path;
if (dirPathArg) path = dirPathArg;
}
updateDirPath(dirPathArg: string) {
this._path = dirPathArg;
}
getKeys() {
return helpers.sshKeyArrayFromDir(this._path);
}
} }

View File

@ -1,103 +1,102 @@
import "typings-global" import * as plugins from './smartssh.plugins';
import * as plugins from "./smartssh.plugins"; import * as helpers from './smartssh.classes.helpers';
import * as helpers from "./smartssh.classes.helpers";
import {SshDir} from "./smartssh.classes.sshdir"; import { SshDir } from './smartssh.classes.sshdir';
import {SshConfig} from "./smartssh.classes.sshconfig"; import { SshConfig } from './smartssh.classes.sshconfig';
import {SshKey} from "./smartssh.classes.sshkey"; import { SshKey } from './smartssh.classes.sshkey';
/**
* SshInstance is the main class dealing with ssh management
*/
export class SshInstance { export class SshInstance {
private _sshKeyArray:SshKey[]; //holds all ssh keys private _sshKeyArray: SshKey[]; // holds all ssh keys
private _sshConfig:SshConfig; // sshConfig (e.g. represents ~/.ssh/config) private _sshConfig: SshConfig; // sshConfig (e.g. represents ~/.ssh/config)
private _sshDir:SshDir; // points to sshDir class instance. private _sshDir: SshDir; // points to sshDir class instance.
private _sshSync:boolean; // if set to true, the ssh dir will be kept in sync automatically private _sshSync: boolean; // if set to true, the ssh dir will be kept in sync automatically
constructor(optionsArg:{sshDirPath?:string,sshSync?:boolean}={}){ constructor(optionsArg: { sshDirPath?: string; sshSync?: boolean } = {}) {
optionsArg ? void(0) : optionsArg = {}; optionsArg ? void 0 : (optionsArg = {});
this._sshKeyArray = []; this._sshKeyArray = [];
this._sshConfig = new SshConfig(this._sshKeyArray); this._sshConfig = new SshConfig(this._sshKeyArray);
this._sshDir = new SshDir(this._sshKeyArray,this._sshConfig,optionsArg.sshDirPath); this._sshDir = new SshDir(this._sshKeyArray, this._sshConfig, optionsArg.sshDirPath);
this._sshSync = optionsArg.sshSync; this._sshSync = optionsArg.sshSync;
}; }
//altering methods // altering methods
addKey(sshKeyArg:SshKey){ addKey(sshKeyArg: SshKey) {
this._syncAuto("from"); this._syncAuto('from');
this._sshKeyArray.push(sshKeyArg); this._sshKeyArray.push(sshKeyArg);
this._syncAuto("to"); this._syncAuto('to');
}; }
removeKey(sshKeyArg:SshKey){ removeKey(sshKeyArg: SshKey) {
this._syncAuto("from"); this._syncAuto('from');
let filteredArray = this._sshKeyArray.filter((sshKeyArg2:SshKey) => { let filteredArray = this._sshKeyArray.filter((sshKeyArg2: SshKey) => {
return (sshKeyArg != sshKeyArg2); return sshKeyArg != sshKeyArg2;
}); });
this._sshKeyArray = filteredArray; this._sshKeyArray = filteredArray;
this._syncAuto("to"); this._syncAuto('to');
}; }
replaceKey(sshKeyOldArg:SshKey,sshKeyNewArg:SshKey){ replaceKey(sshKeyOldArg: SshKey, sshKeyNewArg: SshKey) {
this._syncAuto("from"); this._syncAuto('from');
this.removeKey(sshKeyOldArg); this.removeKey(sshKeyOldArg);
this.addKey(sshKeyNewArg); this.addKey(sshKeyNewArg);
this._syncAuto("to"); this._syncAuto('to');
}; }
// // non altering methods
getKey(hostArg:string):SshKey{ getKey(hostArg: string): SshKey {
this._syncAuto("from"); this._syncAuto('from');
let filteredArray = this._sshKeyArray.filter(function(keyArg){ let filteredArray = this._sshKeyArray.filter(function(keyArg) {
return (keyArg.host == hostArg); return keyArg.host === hostArg;
}); });
if(filteredArray.length > 0){ if (filteredArray.length > 0) {
return filteredArray[0]; return filteredArray[0];
} else { } else {
return undefined; return undefined;
}
};
get sshKeys():SshKey[] {
this._syncAuto("from");
return this._sshKeyArray;
};
//FS methods
/**
* write SshInstance to disk
*/
writeToDisk(){
this._sync("to");
} }
}
get sshKeys(): SshKey[] {
this._syncAuto('from');
return this._sshKeyArray;
}
/** // FS methods
* read ab SshInstance from disk
*/ /**
readFromDisk(){ * write SshInstance to disk
this._sync("from"); */
writeToDisk(dirPathArg?: string) {
this._sync('to', dirPathArg);
}
/**
* read ab SshInstance from disk
*/
readFromDisk(dirPathArg?: string) {
this._sync('from', dirPathArg);
}
/* ===============================================================
========================= Private Methods ========================
================================================================*/
/**
* method to invoke SshInstance _sync automatically when sshSync is true
*/
private _syncAuto(directionArg: 'from' | 'to') {
if (this._sshSync) {
// if auto sync is not enabled, do nothing
this._sync(directionArg);
} }
}
/* =============================================================== /**
========================= Private Methods ======================== * private method to sync SshInstance
================================================================*/ */
private _sync(directionArg: 'from' | 'to', dirPathArg?: string) {
private _makeConfig (){ if (directionArg === 'from') {
this._sshDir.readFromDir(dirPathArg); // call sync method of sshDir class;
} else if (directionArg === 'to') {
this._sshDir.writeToDir(dirPathArg);
} }
}
/**
* method to invoke SshInstance _sync automatically when sshSync is true
*/
private _syncAuto(directionArg){
if(this._sshSync) this._sync(directionArg);
}
/**
* private method to sync SshInstance
*/
private _sync(directionArg:string){
if(directionArg == "from"){
this._sshDir.readFromDir(); // call sync method of sshDir class;
} else if(directionArg == "to") {
this._sshDir.writeToDir();
} else {
throw new Error("directionArg not recognised. Must be 'to' or 'from'");
}
};
} }

View File

@ -1,96 +1,106 @@
import "typings-global"; import * as plugins from './smartssh.plugins';
import * as plugins from "./smartssh.plugins"; import * as helpers from './smartssh.classes.helpers';
import * as helpers from "./smartssh.classes.helpers";
export class SshKey { export class SshKey {
private _privKey:string; private _privKey: string;
private _pubKey:string; private _pubKey: string;
private _hostVar:string; private _hostVar: string;
private _authorized:boolean; private _authorized: boolean;
constructor(optionsArg:{private?:string,public?:string,host?:string,authorized?:boolean}={}){
this._privKey = optionsArg.private;
this._pubKey = optionsArg.public;
this._hostVar = optionsArg.host;
this._authorized = optionsArg.authorized;
};
// this.host private _smarthshellInstance = new plugins.shelljs.Smartshell({
get host(){ executor: 'bash'
return this._hostVar; });
};
set host(hostArg:string){
this._hostVar = hostArg;
};
// this.privKey /**
get privKey(){ * the constructor for class SshKey
return this._privKey; */
}; constructor(
set privKey(privateKeyArg:string){ optionsArg: { private?: string; public?: string; host?: string; authorized?: boolean } = {}
this._privKey = privateKeyArg; ) {
}; this._privKey = optionsArg.private;
this._pubKey = optionsArg.public;
this._hostVar = optionsArg.host;
this._authorized = optionsArg.authorized;
}
// this.privKeyBase64 // this.host
get privKeyBase64(){ get host() {
return plugins.base64.encode(this._privKey); return this._hostVar;
} }
set privKeyBase64(privateKeyArg:string) { set host(hostArg: string) {
this._privKey = plugins.base64.decode(privateKeyArg); this._hostVar = hostArg;
} }
// this.pubKey // this.privKey
get pubKey(){ get privKey() {
return this._pubKey; return this._privKey;
} }
set pubKey(publicKeyArg:string){ set privKey(privateKeyArg: string) {
this._pubKey = publicKeyArg; this._privKey = privateKeyArg;
}; }
// this.pubKeyBase64 // this.privKeyBase64
get pubKeyBase64(){ get privKeyBase64() {
return plugins.base64.encode(this._pubKey); return plugins.smartstring.base64.encode(this._privKey);
} }
set pubKeyBase64(publicKeyArg:string) { set privKeyBase64(privateKeyArg: string) {
this._pubKey = plugins.base64.decode(publicKeyArg); this._privKey = plugins.smartstring.base64.decode(privateKeyArg);
} }
get authorized(){ // this.pubKey
return this._authorized; get pubKey() {
} return this._pubKey;
set authorized(authorizedArg:boolean){ }
this._authorized = authorizedArg; set pubKey(publicKeyArg: string) {
} this._pubKey = publicKeyArg;
get type(){ }
if(this._privKey && this._pubKey){
return "duplex";
} else if(this._privKey){
return "private";
} else if(this._pubKey){
return "public";
}
};
set type(someVlueArg:any){
console.log("the type of an SshKey connot be set. This value is autpcomputed.")
}
// methods // this.pubKeyBase64
read(filePathArg){ 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() {
if (this._privKey && this._pubKey) {
return 'duplex';
} else if (this._privKey) {
return 'private';
} else if (this._pubKey) {
return 'public';
} }
store(dirPathArg:string){ }
plugins.fs.ensureDirSync(dirPathArg); set type(someVlueArg: any) {
let fileNameBase = this.host; console.log('the type of an SshKey connot be set. This value is autocomputed.');
if(this._privKey){ }
let filePath = plugins.path.join(dirPathArg,fileNameBase);
plugins.smartfile.memory.toFsSync(this._privKey,filePath); // methods
plugins.shelljs.chmod(600,filePath); read(filePathArg) {}
};
if (this._pubKey){ async store(dirPathArg: string) {
let filePath = plugins.path.join(dirPathArg,fileNameBase + ".pub"); plugins.fs.ensureDirSync(dirPathArg);
plugins.smartfile.memory.toFsSync(this._pubKey,filePath); let fileNameBase = this.host;
plugins.shelljs.chmod(600,filePath); if (this._privKey) {
} let filePath = plugins.path.join(dirPathArg, fileNameBase);
plugins.smartfile.memory.toFsSync(this._privKey, filePath);
await this._smarthshellInstance.exec(`chmod 0600 ${filePath}`);
} }
if (this._pubKey) {
let filePath = plugins.path.join(dirPathArg, fileNameBase + '.pub');
plugins.smartfile.memory.toFsSync(this._pubKey, filePath);
await this._smarthshellInstance.exec(`chmod 0600 ${filePath}`);
}
}
} }
let testKey = new SshKey();

View File

@ -1,10 +1,10 @@
import "typings-global" import * as fs from 'fs-extra';
export import beautylog = require("beautylog"); import * as minimatch from 'minimatch';
export let base64 = require("js-base64").Base64; import * as path from 'path';
export let fs = require("fs-extra"); import * as smartpromise from '@pushrocks/smartpromise';
export let minimatch = require("minimatch"); import * as shelljs from '@pushrocks/smartshell';
export import path = require("path"); import * as smartfile from '@pushrocks/smartfile';
export let q = require("q"); import * as smartpath from '@pushrocks/smartpath';
export let shelljs = require("shelljs"); import * as smartstring from '@pushrocks/smartstring';
export import smartfile = require("smartfile");
export import smartpath = require("smartpath"); export { fs, minimatch, path, smartpromise, shelljs, smartfile, smartpath, smartstring };

17
tslint.json Normal file
View File

@ -0,0 +1,17 @@
{
"extends": ["tslint:latest", "tslint-config-prettier"],
"rules": {
"semicolon": [true, "always"],
"no-console": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
]
}
}
},
"defaultSeverity": "warning"
}