32 Commits

Author SHA1 Message Date
9fc03e8504 2.0.1 2023-07-27 15:52:02 +02:00
9a32b156fe fix(core): update 2023-07-27 15:52:01 +02:00
a319e54d60 2.0.0 2022-10-11 13:18:35 +02:00
6a2577cde6 BREAKING CHANGE(core): switch to esm 2022-10-11 13:18:35 +02:00
1f1bf7c21f 1.2.7 2022-10-11 13:18:04 +02:00
c652d0bf07 fix(core): update 2022-10-11 13:18:04 +02:00
eccc6294a8 1.2.6 2022-10-11 13:13:14 +02:00
f8a75a8d42 fix(core): update 2022-10-11 13:13:14 +02:00
d5c2bc1b53 1.2.5 2022-10-11 13:05:30 +02:00
d577a82a7b fix(core): update 2022-10-11 13:05:29 +02:00
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
5091625953 1.1.5 2016-06-26 16:16:28 +02:00
f74b3a51b0 now creating config as standard 2016-06-26 16:16:12 +02:00
062f3ad060 1.1.4 2016-06-26 04:23:48 +02:00
ecd0fd8fad now setting rights for stored keys 2016-06-26 04:23:45 +02:00
742bf694e4 1.1.3 2016-06-26 04:07:37 +02:00
38165f11db some updates 2016-06-26 04:07:03 +02:00
ef2b31b4b2 1.1.2 2016-06-25 15:31:03 +02:00
5b1f800067 update structure 2016-06-25 15:30:57 +02:00
6339a3ed9b update SshKey.store() 2016-06-25 14:13:26 +02:00
bf27aaf167 update structure 2016-06-25 13:07:24 +02:00
50 changed files with 5592 additions and 906 deletions

@ -0,0 +1,66 @@
name: Default (not tags)
on:
push:
tags-ignore:
- '**'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Install pnpm and npmci
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
- name: Run npm prepare
run: npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build

@ -0,0 +1,124 @@
name: Default (tags)
on:
push:
tags:
- '*'
env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
jobs:
security:
runs-on: ubuntu-latest
continue-on-error: true
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Audit production dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --prod
continue-on-error: true
- name: Audit development dependencies
run: |
npmci command npm config set registry https://registry.npmjs.org
npmci command pnpm audit --audit-level=high --dev
continue-on-error: true
test:
if: ${{ always() }}
needs: security
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Test stable
run: |
npmci node install stable
npmci npm install
npmci npm test
- name: Test build
run: |
npmci node install stable
npmci npm install
npmci npm build
release:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Release
run: |
npmci node install stable
npmci npm publish
metadata:
needs: test
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
container:
image: ${{ env.IMAGE }}
continue-on-error: true
steps:
- uses: actions/checkout@v3
- name: Prepare
run: |
pnpm install -g pnpm
pnpm install -g @shipzone/npmci
npmci npm prepare
- name: Code quality
run: |
npmci command npm install -g typescript
npmci npm install
- name: Trigger
run: npmci trigger
- name: Build docs and upload artifacts
run: |
npmci node install stable
npmci npm install
pnpm install -g @gitzone/tsdoc
npmci command tsdoc
continue-on-error: true

25
.gitignore vendored

@ -1,7 +1,20 @@
.idea/ .nogit/
node_modules/
# artifacts
coverage/ coverage/
docs/ public/
ts/typings/ pages/
ts/*.js
ts/*.js.map # installs
node_modules/
# caches
.yarn/
.cache/
.rpt2_cache
# builds
dist/
dist_*/
# custom

@ -1,38 +0,0 @@
image: hosttoday/ht-docker-node:npmts
stages:
- test
- release
- page
testLTS:
stage: test
script:
- npmci test lts
tags:
- docker
- lossless
testSTABLE:
stage: test
script:
- npmci test stable
tags:
- docker
- lossless
testLEGACY:
stage: test
script:
- npmci test legacy
allow_failure: true
release:
stage: release
script:
- npmci publish
only:
- tags
tags:
- docker
- lossless

@ -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

11
.vscode/launch.json vendored Normal file

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "npm test",
"name": "Run npm test",
"request": "launch",
"type": "node-terminal"
}
]
}

26
.vscode/settings.json vendored Normal file

@ -0,0 +1,26 @@
{
"json.schemas": [
{
"fileMatch": ["/npmextra.json"],
"schema": {
"type": "object",
"properties": {
"npmci": {
"type": "object",
"description": "settings for npmci"
},
"gitzone": {
"type": "object",
"description": "settings for gitzone",
"properties": {
"projectType": {
"type": "string",
"enum": ["website", "element", "service", "npm", "wcc"]
}
}
}
}
}
}
]
}

@ -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

@ -1,34 +0,0 @@
# smartssh
setups SSH quickly and in a painless manner
> Attention: This is still alpha, so some things won't work, not all things are inplemented.
## Usage
```javascript
var smartssh = require("smartssh");
var sshInstance = new smartssh.sshInstance({
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;
});
sshInstance.addKey(new smartssh.sshKey({
private: "somestring",
public: "somestring", // optional
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.createKey({
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
```

5
dist/index.d.ts vendored

@ -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

@ -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

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

@ -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==

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

@ -1,24 +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.storeConfig = function (dirPathArg) {
var done = plugins.q.defer();
var configArray;
return done.promise;
};
return SshConfig;
}());
exports.SshConfig = SshConfig;
;
var createConfigPath = function () {
};
;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLmNsYXNzZXMuc3NoY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUFnQixDQUFDLENBQUE7QUFDeEIsSUFBWSxPQUFPLFdBQU0sb0JBQW9CLENBQUMsQ0FBQTtBQUk5QztJQUVJLG1CQUFZLGNBQXVCO1FBQy9CLElBQUksQ0FBQyxXQUFXLEdBQUcsY0FBYyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7T0FFRztJQUNILCtCQUFXLEdBQVgsVUFBWSxVQUFpQjtRQUN6QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzdCLElBQUksV0FBMEIsQ0FBQztRQUUvQixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN4QixDQUFDO0lBQ0wsZ0JBQUM7QUFBRCxDQWZBLEFBZUMsSUFBQTtBQWZZLGlCQUFTLFlBZXJCLENBQUE7QUFBQSxDQUFDO0FBRUYsSUFBSSxnQkFBZ0IsR0FBRztBQUV2QixDQUFDLENBQUE7QUFNQSxDQUFDIiwiZmlsZSI6InNtYXJ0c3NoLmNsYXNzZXMuc3NoY29uZmlnLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIjtcbmltcG9ydCAqIGFzIHBsdWdpbnMgZnJvbSBcIi4vc21hcnRzc2gucGx1Z2luc1wiO1xuaW1wb3J0ICogYXMgaGVscGVycyBmcm9tIFwiLi9zbWFydHNzaC5jbGFzc2VzLmhlbHBlcnNcIjtcbmltcG9ydCB7U3NoS2V5fSBmcm9tIFwiLi9zbWFydHNzaC5jbGFzc2VzLnNzaGtleVwiXG5cbmV4cG9ydCBjbGFzcyBTc2hDb25maWcge1xuICAgIHNzaEtleUFycmF5OlNzaEtleVtdO1xuICAgIGNvbnN0cnVjdG9yKHNzaEtleUFycmF5QXJnOlNzaEtleVtdKXtcbiAgICAgICAgdGhpcy5zc2hLZXlBcnJheSA9IHNzaEtleUFycmF5QXJnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHN0b3JlcyBhIGNvbmZpZyBmaWxlXG4gICAgICovXG4gICAgc3RvcmVDb25maWcoZGlyUGF0aEFyZzpzdHJpbmcpe1xuICAgICAgICBsZXQgZG9uZSA9IHBsdWdpbnMucS5kZWZlcigpO1xuICAgICAgICBsZXQgY29uZmlnQXJyYXk6Y29uZmlnT2JqZWN0W107XG5cbiAgICAgICAgcmV0dXJuIGRvbmUucHJvbWlzZTtcbiAgICB9XG59O1xuXG5sZXQgY3JlYXRlQ29uZmlnUGF0aCA9ICgpID0+IHtcbiAgICBcbn1cblxuZXhwb3J0IGludGVyZmFjZSBjb25maWdPYmplY3Qge1xuICAgIGhvc3Q6c3RyaW5nO1xuICAgIGF1dGhvcml6ZWQ6Ym9vbGVhbjtcbiAgICBzc2hLZXk6U3NoS2V5O1xufTtcblxuIl19

@ -1,10 +0,0 @@
import "typings-global";
import { SshKey } from "./smartssh.classes.sshkey";
export declare class SshDir {
path: string;
private sshKeyArray;
constructor(sshKeyArray: SshKey[], sshDirPathArg?: string);
writeToDir(): void;
readFromDir(): void;
getKeys(): SshKey[];
}

@ -1,32 +0,0 @@
"use strict";
require("typings-global");
var plugins = require("./smartssh.plugins");
var helpers = require("./smartssh.classes.helpers");
var SshDir = (function () {
function SshDir(sshKeyArray, sshDirPathArg) {
this.sshKeyArray = sshKeyArray;
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);
});
};
;
SshDir.prototype.readFromDir = function () {
};
SshDir.prototype.getKeys = function () {
return helpers.sshKeyArrayFromDir(this.path);
};
return SshDir;
}());
exports.SshDir = SshDir;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLmNsYXNzZXMuc3NoZGlyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUFnQixDQUFDLENBQUE7QUFDeEIsSUFBWSxPQUFPLFdBQU0sb0JBQW9CLENBQUMsQ0FBQTtBQUM5QyxJQUFZLE9BQU8sV0FBTSw0QkFBNEIsQ0FBQyxDQUFBO0FBSXREO0lBR0ksZ0JBQVksV0FBb0IsRUFBQyxhQUFxQjtRQUNsRCxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUMvQixFQUFFLENBQUEsQ0FBQyxhQUFhLENBQUMsQ0FBQSxDQUFDO1lBQ2QsSUFBSSxDQUFDLElBQUksR0FBRyxhQUFhLENBQUM7UUFDOUIsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ0osSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBQyxPQUFPLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQUEsQ0FBQztJQUNOLENBQUM7SUFDRCwyQkFBVSxHQUFWO1FBQUEsaUJBS0M7UUFKRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFDLFNBQVM7WUFDL0IsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFL0IsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDOztJQUNELDRCQUFXLEdBQVg7SUFFQSxDQUFDO0lBQ0Qsd0JBQU8sR0FBUDtRQUNJLE1BQU0sQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFDTCxhQUFDO0FBQUQsQ0F2QkEsQUF1QkMsSUFBQTtBQXZCWSxjQUFNLFNBdUJsQixDQUFBIiwiZmlsZSI6InNtYXJ0c3NoLmNsYXNzZXMuc3NoZGlyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIjtcbmltcG9ydCAqIGFzIHBsdWdpbnMgZnJvbSBcIi4vc21hcnRzc2gucGx1Z2luc1wiO1xuaW1wb3J0ICogYXMgaGVscGVycyBmcm9tIFwiLi9zbWFydHNzaC5jbGFzc2VzLmhlbHBlcnNcIjtcbmltcG9ydCB7U3NoSW5zdGFuY2V9IGZyb20gXCIuL3NtYXJ0c3NoLmNsYXNzZXMuc3NoaW5zdGFuY2VcIjtcbmltcG9ydCB7U3NoS2V5fSBmcm9tIFwiLi9zbWFydHNzaC5jbGFzc2VzLnNzaGtleVwiO1xuaW1wb3J0IHtTc2hDb25maWd9IGZyb20gXCIuL3NtYXJ0c3NoLmNsYXNzZXMuc3NoY29uZmlnXCI7XG5leHBvcnQgY2xhc3MgU3NoRGlyIHsgLy8gc3NoRGlyIGNsYXNzIC0+IE5PVCBFWFBPUlRFRCwgT05MWSBGT1IgSU5URVJOQUwgVVNFXG4gICAgcGF0aDpzdHJpbmc7IC8vIHRoZSBwYXRoIG9mIHRoZSBzc2ggZGlyZWN0b3J5XG4gICAgcHJpdmF0ZSBzc2hLZXlBcnJheTpTc2hLZXlbXTtcbiAgICBjb25zdHJ1Y3Rvcihzc2hLZXlBcnJheTpTc2hLZXlbXSxzc2hEaXJQYXRoQXJnPzpzdHJpbmcpe1xuICAgICAgICB0aGlzLnNzaEtleUFycmF5ID0gc3NoS2V5QXJyYXk7XG4gICAgICAgIGlmKHNzaERpclBhdGhBcmcpe1xuICAgICAgICAgICAgdGhpcy5wYXRoID0gc3NoRGlyUGF0aEFyZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucGF0aCA9IHBsdWdpbnMucGF0aC5qb2luKHBsdWdpbnMuc21hcnRwYXRoLmdldC5ob21lKCksXCIuc3NoL1wiKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgd3JpdGVUb0RpcigpeyAvLyBzeW5jcyBzc2hJbnN0YW5jZSB0byBkaXJlY3RvcnlcbiAgICAgICAgdGhpcy5zc2hLZXlBcnJheS5mb3JFYWNoKChzc2hLZXlBcmcpID0+IHtcbiAgICAgICAgICAgIHNzaEtleUFyZy5zdG9yZSh0aGlzLnBhdGgpO1xuICAgICAgICAgICAgXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmVhZEZyb21EaXIoKXsgLy8gc3luY3Mgc3NoSW5zdGFuY2UgZnJvbSBkaXJlY3RvcnlcbiAgICAgICAgXG4gICAgfVxuICAgIGdldEtleXMoKXtcbiAgICAgICAgcmV0dXJuIGhlbHBlcnMuc3NoS2V5QXJyYXlGcm9tRGlyKHRoaXMucGF0aCk7XG4gICAgfVxufSJdfQ==

@ -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

@ -1,21 +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;
type: any;
read(filePathArg: any): void;
store(filePathArg?: string): void;
}

File diff suppressed because one or more lines are too long

@ -1,9 +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 import smartfile = require("smartfile");
export import smartpath = require("smartpath");

@ -1,12 +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.smartfile = require("smartfile");
exports.smartpath = require("smartpath");
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sZ0JBQ1AsQ0FBQyxDQURzQjtBQUNULGlCQUFTLFdBQVcsV0FBVyxDQUFDLENBQUM7QUFDcEMsY0FBTSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDckMsVUFBRSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUN6QixpQkFBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUM5QixZQUFJLFdBQVcsTUFBTSxDQUFDLENBQUM7QUFDMUIsU0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLGlCQUFTLFdBQVcsV0FBVyxDQUFDLENBQUM7QUFDakMsaUJBQVMsV0FBVyxXQUFXLENBQUMsQ0FBQyIsImZpbGUiOiJzbWFydHNzaC5wbHVnaW5zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIlxuZXhwb3J0IGltcG9ydCBiZWF1dHlsb2cgPSByZXF1aXJlKFwiYmVhdXR5bG9nXCIpO1xuZXhwb3J0IGxldCBiYXNlNjQgPSByZXF1aXJlKFwianMtYmFzZTY0XCIpLkJhc2U2NDtcbmV4cG9ydCBsZXQgZnMgPSByZXF1aXJlKFwiZnMtZXh0cmFcIik7XG5leHBvcnQgbGV0IG1pbmltYXRjaCA9IHJlcXVpcmUoXCJtaW5pbWF0Y2hcIik7XG5leHBvcnQgaW1wb3J0IHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcbmV4cG9ydCBsZXQgcSA9IHJlcXVpcmUoXCJxXCIpO1xuZXhwb3J0IGltcG9ydCBzbWFydGZpbGUgPSByZXF1aXJlKFwic21hcnRmaWxlXCIpO1xuZXhwb3J0IGltcG9ydCBzbWFydHBhdGggPSByZXF1aXJlKFwic21hcnRwYXRoXCIpOyJdfQ==

17
npmextra.json Normal file

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

@ -1,3 +0,0 @@
{
"mode":"default"
}

@ -1,11 +1,16 @@
{ {
"name": "smartssh", "name": "@push.rocks/smartssh",
"version": "1.1.1", "version": "2.0.1",
"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_ts/index.js",
"typings": "dist/index.d.ts", "typings": "dist_ts/index.d.ts",
"type": "module",
"scripts": { "scripts": {
"test": "(npmts)" "test": "(tstest test/)",
"testDocker": "tsdocker",
"build": "(tsbuild --allowimplicitany)",
"buildDocs": "tsdoc"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -23,18 +28,35 @@
}, },
"homepage": "https://gitlab.com/pushrocks/smartssh#readme", "homepage": "https://gitlab.com/pushrocks/smartssh#readme",
"dependencies": { "dependencies": {
"beautylog": "^5.0.12", "@push.rocks/smartfile": "^10.0.28",
"fs-extra": "^0.30.0", "@push.rocks/smartpath": "^5.0.11",
"js-base64": "^2.1.9", "@push.rocks/smartpromise": "^4.0.3",
"minimatch": "^3.0.2", "@push.rocks/smartshell": "^3.0.3",
"q": "^1.4.1", "@push.rocks/smartstring": "^4.0.7",
"smartfile": "^4.0.5", "@types/fs-extra": "^11.0.1",
"smartpath": "^3.2.2", "fs-extra": "^11.1.1",
"typings-global": "^1.0.3", "minimatch": "^9.0.3"
"typings-test": "^1.0.1"
}, },
"devDependencies": { "devDependencies": {
"npmts-g": "^5.2.6", "@gitzone/tsbuild": "^2.1.66",
"should": "^9.0.2" "@gitzone/tsrun": "^1.2.44",
} "@gitzone/tstest": "^1.0.77",
"@push.rocks/tapbundle": "^5.0.12",
"@types/node": "^20.4.5"
},
"files": [
"ts/**/*",
"ts_web/**/*",
"dist/**/*",
"dist_*/**/*",
"dist_ts/**/*",
"dist_ts_web/**/*",
"assets/**/*",
"cli.js",
"npmextra.json",
"readme.md"
],
"browserslist": [
"last 1 chrome versions"
]
} }

4794
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

65
readme.md Normal file

@ -0,0 +1,65 @@
# @push.rocks/smartssh
setups SSH quickly and in a painless manner
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@push.rocks/smartssh)
* [gitlab.com (source)](https://gitlab.com/push.rocks/smartssh)
* [github.com (source mirror)](https://github.com/push.rocks/smartssh)
* [docs (typedoc)](https://push.rocks.gitlab.io/smartssh/)
## Status for master
Status Category | Status Badge
-- | --
GitLab Pipelines | [![pipeline status](https://gitlab.com/push.rocks/smartssh/badges/master/pipeline.svg)](https://lossless.cloud)
GitLab Pipline Test Coverage | [![coverage report](https://gitlab.com/push.rocks/smartssh/badges/master/coverage.svg)](https://lossless.cloud)
npm | [![npm downloads per month](https://badgen.net/npm/dy/@push.rocks/smartssh)](https://lossless.cloud)
Snyk | [![Known Vulnerabilities](https://badgen.net/snyk/push.rocks/smartssh)](https://lossless.cloud)
TypeScript Support | [![TypeScript](https://badgen.net/badge/TypeScript/>=%203.x/blue?icon=typescript)](https://lossless.cloud)
node Support | [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
Code Style | [![Code Style](https://badgen.net/badge/style/prettier/purple)](https://lossless.cloud)
PackagePhobia (total standalone install weight) | [![PackagePhobia](https://badgen.net/packagephobia/install/@push.rocks/smartssh)](https://lossless.cloud)
PackagePhobia (package size on registry) | [![PackagePhobia](https://badgen.net/packagephobia/publish/@push.rocks/smartssh)](https://lossless.cloud)
BundlePhobia (total size when bundled) | [![BundlePhobia](https://badgen.net/bundlephobia/minzip/@push.rocks/smartssh)](https://lossless.cloud)
## Usage
```javascript
var smartssh = require('smartssh');
var sshInstance = new smartssh.sshInstance({
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;
});
sshInstance.addKey(
new smartssh.sshKey({
private: 'somestring',
public: 'somestring', // optional
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.createKey({
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
```
## Contribution
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
For further information read the linked docs at the top of this readme.
## Legal
> MIT licensed | **©** [Task Venture Capital GmbH](https://task.vc)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)

1
test/temp/bitbucket.org Normal file

@ -0,0 +1 @@
somePrivateKey

@ -0,0 +1 @@
somePublicKey

15
test/temp/config Normal 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

@ -0,0 +1 @@
someExamplePrivateKey

@ -0,0 +1 @@
someExamplePublicKey

1
test/temp/github.com Normal file

@ -0,0 +1 @@
someGitHubPrivateKey

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

@ -0,0 +1 @@
someGitHubPublicKey

1
test/temp/gitlab.com Normal file

@ -0,0 +1 @@
somePrivateKey

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

@ -0,0 +1 @@
somePublicKey

2
test/test.d.ts vendored

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

File diff suppressed because one or more lines are too long

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

8
ts/00_commitinfo_data.ts Normal file

@ -0,0 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
*/
export const commitinfo = {
name: '@push.rocks/smartssh',
version: '2.0.1',
description: 'setups SSH quickly and in a painless manner'
}

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

@ -1,8 +1,7 @@
import "typings-global" import * as plugins from './smartssh.plugins.js';
import * as plugins from "./smartssh.plugins"; import { SshKey } from './smartssh.classes.sshkey.js';
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;
} };

@ -1,32 +1,60 @@
import "typings-global"; import * as plugins from './smartssh.plugins.js';
import * as plugins from "./smartssh.plugins"; import * as helpers from './smartssh.classes.helpers.js';
import * as helpers from "./smartssh.classes.helpers"; import { SshKey } from './smartssh.classes.sshkey.js';
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
*/ */
storeConfig(dirPathArg:string){ store(dirPathArg: string) {
let done = plugins.q.defer(); let done = plugins.smartpromise.defer();
let configArray: configObject[] = [];
let configString;
for (let key in this._sshKeyArray) {
let 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,
});
}
let configFile: string = '';
for (let key in configArray) {
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[]; let configArray: configObject[];
plugins.smartfile.fs.toStringSync(plugins.path.join(dirPathArg, 'config'));
return done.promise; return done.promise;
} }
};
let createConfigPath = () => {
} }
export interface configObject { export interface configObject {
host:string; configString: string;
authorized: boolean; authorized: boolean;
sshKey: SshKey; sshKey: SshKey;
}; }

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

@ -1,105 +1,102 @@
import "typings-global" import * as plugins from './smartssh.plugins.js';
import * as plugins from "./smartssh.plugins"; import * as helpers from './smartssh.classes.helpers.js';
import * as helpers from "./smartssh.classes.helpers";
import {SshDir} from "./smartssh.classes.sshdir"; import { SshDir } from './smartssh.classes.sshdir.js';
import {SshConfig} from "./smartssh.classes.sshconfig"; import { SshConfig } from './smartssh.classes.sshconfig.js';
import {SshKey} from "./smartssh.classes.sshkey"; import { SshKey } from './smartssh.classes.sshkey.js';
/**
* 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,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[] { get sshKeys(): SshKey[] {
this._syncAuto("from"); this._syncAuto('from');
return this._sshKeyArray; return this._sshKeyArray;
}; }
// FS methods // FS methods
/** /**
* write SshInstance to disk * write SshInstance to disk
*/ */
writeToDisk(){ writeToDisk(dirPathArg?: string) {
this._sync("to"); this._sync('to', dirPathArg);
} }
/** /**
* read ab SshInstance from disk * read ab SshInstance from disk
*/ */
readFromDisk(){ readFromDisk(dirPathArg?: string) {
this._sync("from"); this._sync('from', dirPathArg);
} }
/* =============================================================== /* ===============================================================
========================= Private Methods ======================== ========================= Private Methods ========================
================================================================*/ ================================================================*/
private _makeConfig (){
}
/** /**
* method to invoke SshInstance _sync automatically when sshSync is true * method to invoke SshInstance _sync automatically when sshSync is true
*/ */
private _syncAuto(directionArg){ private _syncAuto(directionArg: 'from' | 'to') {
if(this._sshSync) this._sync(directionArg); if (this._sshSync) {
// if auto sync is not enabled, do nothing
this._sync(directionArg);
}
} }
/** /**
* private method to sync SshInstance * private method to sync SshInstance
*/ */
private _sync(directionArg:string){ private _sync(directionArg: 'from' | 'to', dirPathArg?: string) {
if(directionArg == "from"){ if (directionArg === 'from') {
this._sshDir.readFromDir(); // call sync method of sshDir class; this._sshDir.readFromDir(dirPathArg); // call sync method of sshDir class;
} else if(directionArg == "to") { } else if (directionArg === 'to') {
this._sshDir.writeToDir(); this._sshDir.writeToDir(dirPathArg);
} else { }
throw new Error("directionArg not recognised. Must be 'to' or 'from'");
} }
};
} }

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

@ -1,9 +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 '@push.rocks/smartpromise';
export let minimatch = require("minimatch"); import * as shelljs from '@push.rocks/smartshell';
export import path = require("path"); import * as smartfile from '@push.rocks/smartfile';
export let q = require("q"); import * as smartpath from '@push.rocks/smartpath';
export import smartfile = require("smartfile"); import * as smartstring from '@push.rocks/smartstring';
export import smartpath = require("smartpath");
export { fs, minimatch, path, smartpromise, shelljs, smartfile, smartpath, smartstring };

@ -1,8 +0,0 @@
{
"version": false,
"dependencies": {},
"ambientDependencies": {
"colors": "registry:dt/colors#0.6.0-1+20160317120654",
"node": "registry:dt/node#4.0.0+20160423143914"
}
}

11
tsconfig.json Normal file

@ -0,0 +1,11 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"useDefineForClassFields": false,
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "nodenext",
"esModuleInterop": true,
"verbatimModuleSyntax": true,
}
}