63 Commits

Author SHA1 Message Date
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
9bc3aea59c 1.1.1 2016-06-25 02:53:09 +02:00
f5ff302d4d updated structure of SshConfig 2016-06-25 02:53:05 +02:00
cac8203bf5 1.1.0 2016-06-25 02:29:51 +02:00
e4532271cc major structural update 2016-06-25 02:29:34 +02:00
faf6c91199 update 2016-06-25 02:10:53 +02:00
d0009e7a9c update stucture 2016-06-24 20:58:55 +02:00
da76df2c3e 1.0.7 2016-06-24 02:50:02 +02:00
a43976110a update structure 2016-06-24 02:49:55 +02:00
c3ee35a699 1.0.6 2016-06-14 00:34:07 +02:00
a0ce759552 update links in package.json to point to gitlab 2016-06-14 00:33:59 +02:00
201d5cc6d7 some restructuring 2016-06-14 00:27:55 +02:00
e5bdfff743 added ability to add keys as base 64 2016-06-14 00:11:20 +02:00
967c9fd9d1 now using legacy tag in gitlab-ci.yml 2016-06-13 23:31:41 +02:00
35da2f0b73 strip pages from gitlab-ci for now 2016-06-13 23:29:37 +02:00
5e991a4e4f update gitlab ci base image 2016-06-13 23:26:54 +02:00
0f75f5238c update dependencies 2016-06-13 23:26:36 +02:00
e8f3047ac0 1.0.5 2016-06-01 05:18:08 +02:00
812d28ee3d add typings to package.json 2016-06-01 05:17:49 +02:00
fa301eea71 improved tests and reached 80% coverage milestone. 2016-06-01 05:09:20 +02:00
48ccf317d6 update some cosmetics 2016-06-01 04:25:59 +02:00
9b3af8a50a 1.0.4 2016-06-01 04:18:40 +02:00
78aa36c2be added more tests 2016-06-01 04:18:31 +02:00
09d96fd94c update directory sync 2016-06-01 03:57:17 +02:00
f4f60a685d 1.0.3 2016-06-01 02:48:45 +02:00
904129706c add some tests 2016-06-01 02:48:38 +02:00
9a96bbd266 update gitlab ci yml 2016-06-01 02:35:12 +02:00
39abfd760b start tests 2016-06-01 02:31:29 +02:00
1b30aa428e update gitlab-ci yml 2016-06-01 01:00:29 +02:00
41613c0b93 update ci yml 2016-06-01 00:59:02 +02:00
2d14617b13 rename Ssh class to SshInstance 2016-06-01 00:56:24 +02:00
3106945b47 update gitlab ci yml 2016-05-31 19:50:43 +02:00
2284620387 1.0.2 2016-05-31 19:16:52 +02:00
cd6bcb974c made all classes start with capital letters 2016-05-31 19:16:45 +02:00
eb66ed0244 restructure class files 2016-05-31 19:00:52 +02:00
d12c7ab621 update typings to use typings-global and typings-test, update dependencies 2016-05-31 18:48:46 +02:00
84374299cf latest status 2016-04-28 00:09:17 +02:00
b73928109b improve sync triggering 2016-04-26 05:09:03 +02:00
1d17dd1b84 add removeKey and replaceKey methods 2016-04-26 05:04:36 +02:00
1663d9a266 add some logic 2016-04-26 04:44:50 +02:00
36 changed files with 4920 additions and 301 deletions

25
.gitignore vendored
View File

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

128
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,128 @@
# gitzone ci_default
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: '$CI_BUILD_STAGE'
stages:
- security
- test
- release
- metadata
before_script:
- npm install -g @shipzone/npmci
# ====================
# security stage
# ====================
auditProductionDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --production --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=prod --production
tags:
- docker
allow_failure: true
auditDevDependencies:
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
stage: security
script:
- npmci npm prepare
- npmci command npm install --ignore-scripts
- npmci command npm config set registry https://registry.npmjs.org
- npmci command npm audit --audit-level=high --only=dev
tags:
- docker
allow_failure: true
# ====================
# test stage
# ====================
testStable:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
testBuild:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
only:
- tags
tags:
- lossless
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
allow_failure: true
only:
- tags
script:
- npmci command npm install -g typescript
- npmci npm prepare
- npmci npm install
tags:
- lossless
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- lossless
- docker
- notpriv
pages:
stage: metadata
script:
- npmci node install stable
- npmci npm prepare
- npmci npm install
- npmci command npm run buildDocs
tags:
- lossless
- docker
- 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

11
.vscode/launch.json vendored Normal file
View 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
View 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"]
}
}
}
}
}
}
]
}

View File

@ -1,6 +1,6 @@
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
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,33 +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.
I (Phil from Lossless) expect this to be ready 2016/05/01.
## 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
for:"github.com",
encoding: "base64" // optional, defaults to "utf8", can be "utf8" or "base64", useful for reading ssh keys from environment variables
}));
sshInstance.createKey({
for:"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
for:"github.com"
});
sshInstance.getKeys() // returns array of all available getKeys. Each key is in form of class sshKey
```

3
dist/index.js vendored
View File

@ -1,3 +0,0 @@
"use strict";
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbXSwic291cmNlUm9vdCI6Ii9zb3VyY2UvIn0=

View File

@ -1,7 +0,0 @@
"use strict";
exports.sshKeyArrayFromDir = function (dirArg) {
var sshKeyArray = [];
return sshKeyArray;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLmNsYXNzZXMuaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBSVcsMEJBQWtCLEdBQUcsVUFBUyxNQUFhO0lBQ2xELElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQztJQUNyQixNQUFNLENBQUMsV0FBVyxDQUFDO0FBQ3ZCLENBQUMsQ0FBQSIsImZpbGUiOiJzbWFydHNzaC5jbGFzc2VzLmhlbHBlcnMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSBwYXRoPVwiLi90eXBpbmdzL21haW4uZC50c1wiIC8+XG5pbXBvcnQgcGx1Z2lucyA9IHJlcXVpcmUoXCIuL3NtYXJ0c3NoLnBsdWdpbnNcIik7XG5pbXBvcnQgY2xhc3NlcyA9IHJlcXVpcmUoXCIuL3NtYXJ0c3NoLmNsYXNzZXNcIik7XG5cbmV4cG9ydCBsZXQgc3NoS2V5QXJyYXlGcm9tRGlyID0gZnVuY3Rpb24oZGlyQXJnOnN0cmluZyk6Y2xhc3Nlcy5zc2hLZXlbXXtcbiAgICBsZXQgc3NoS2V5QXJyYXkgPSBbXTtcbiAgICByZXR1cm4gc3NoS2V5QXJyYXk7XG59Il0sInNvdXJjZVJvb3QiOiIvc291cmNlLyJ9

File diff suppressed because one or more lines are too long

View File

@ -1,9 +0,0 @@
"use strict";
/// <reference path="./typings/main.d.ts" />
exports.beautylog = require("beautylog");
exports.base64 = require("js-base64").Base64;
exports.fs = require("fs-extra");
exports.path = require("path");
exports.smartfile = require("smartfile");
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNtYXJ0c3NoLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDRDQUE0QztBQUNqQyxpQkFBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUNqQyxjQUFNLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUNyQyxVQUFFLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3pCLFlBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdkIsaUJBQVMsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMiLCJmaWxlIjoic21hcnRzc2gucGx1Z2lucy5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuL3R5cGluZ3MvbWFpbi5kLnRzXCIgLz5cbmV4cG9ydCBsZXQgYmVhdXR5bG9nID0gcmVxdWlyZShcImJlYXV0eWxvZ1wiKTtcbmV4cG9ydCBsZXQgYmFzZTY0ID0gcmVxdWlyZShcImpzLWJhc2U2NFwiKS5CYXNlNjQ7XG5leHBvcnQgbGV0IGZzID0gcmVxdWlyZShcImZzLWV4dHJhXCIpO1xuZXhwb3J0IGxldCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XG5leHBvcnQgbGV0IHNtYXJ0ZmlsZSA9IHJlcXVpcmUoXCJzbWFydGZpbGVcIik7Il0sInNvdXJjZVJvb3QiOiIvc291cmNlLyJ9

17
npmextra.json Normal file
View File

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

View File

@ -1,14 +1,20 @@
{
"name": "smartssh",
"version": "1.0.1",
"name": "@pushrocks/smartssh",
"version": "1.2.5",
"private": false,
"description": "setups SSH quickly and in a painless manner",
"main": "dist/index.js",
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"type": "module",
"scripts": {
"test": "(npmts)"
"test": "(tstest test/)",
"testDocker": "tsdocker",
"build": "(tsbuild)",
"buildDocs": "tsdoc"
},
"repository": {
"type": "git",
"url": "git+https://github.com/pushrocks/smartssh.git"
"url": "git+https://gitlab.com/pushrocks/smartssh.git"
},
"keywords": [
"SSH",
@ -18,17 +24,40 @@
"author": "Lossless GmbH",
"license": "MIT",
"bugs": {
"url": "https://github.com/pushrocks/smartssh/issues"
"url": "https://gitlab.com/pushrocks/smartssh/issues"
},
"homepage": "https://github.com/pushrocks/smartssh#readme",
"homepage": "https://gitlab.com/pushrocks/smartssh#readme",
"dependencies": {
"beautylog": "^4.1.2",
"fs-extra": "^0.28.0",
"js-base64": "^2.1.9",
"smartfile": "^3.0.5"
"@pushrocks/smartfile": "^10.0.5",
"@pushrocks/smartpath": "^5.0.5",
"@pushrocks/smartpromise": "^3.0.2",
"@pushrocks/smartshell": "^2.0.23",
"@pushrocks/smartstring": "^4.0.5",
"@types/fs-extra": "^9.0.13",
"@types/minimatch": "^5.1.2",
"fs-extra": "^10.1.0",
"minimatch": "^5.1.0"
},
"devDependencies": {
"npmts": "^5.0.4",
"should": "^8.3.1"
}
"@gitzone/tsbuild": "^2.1.11",
"@gitzone/tsrun": "^1.2.6",
"@gitzone/tstest": "^1.0.24",
"@pushrocks/tapbundle": "^5.0.4",
"@types/node": "^18.8.4"
},
"files": [
"ts/**/*",
"ts_web/**/*",
"dist/**/*",
"dist_*/**/*",
"dist_ts/**/*",
"dist_ts_web/**/*",
"assets/**/*",
"cli.js",
"npmextra.json",
"readme.md"
],
"browserslist": [
"last 1 chrome versions"
]
}

4213
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

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

View File

@ -1,5 +0,0 @@
/// <reference path="../ts/typings/main.d.ts" />
var should = require("should");
var smartssh = require("../dist/index.js");
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0RBQWdEO0FBQ2hELElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMvQixJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQyIsImZpbGUiOiJ0ZXN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uL3RzL3R5cGluZ3MvbWFpbi5kLnRzXCIgLz5cbmxldCBzaG91bGQgPSByZXF1aXJlKFwic2hvdWxkXCIpO1xubGV0IHNtYXJ0c3NoID0gcmVxdWlyZShcIi4uL2Rpc3QvaW5kZXguanNcIik7XG4iXSwic291cmNlUm9vdCI6Ii9zb3VyY2UvIn0=

View File

@ -1,3 +1,84 @@
/// <reference path="../ts/typings/main.d.ts" />
let should = require("should");
let smartssh = require("../dist/index.js");
import { expect, tap } from '@pushrocks/tapbundle';
import * as smartssh from '../ts/index.js';
import * as path from 'path';
let testSshInstance: smartssh.SshInstance;
let testSshKey: smartssh.SshKey;
tap.test('should create a valid SshKey object', async () => {
testSshKey = new smartssh.SshKey({
host: 'example.com',
private: 'someExamplePrivateKey',
public: 'someExamplePublicKey',
});
expect(testSshKey).toBeInstanceOf(smartssh.SshKey);
});
tap.test('.type should be a valid type', async () => {
expect(testSshKey.type).toEqual('duplex');
});
tap.test('.publicKey should be public key', async () => {
expect(testSshKey.pubKey).toEqual('someExamplePublicKey');
});
tap.test('.privateKey should be private key', async () => {
expect(testSshKey.privKey).toEqual('someExamplePrivateKey');
});
tap.test('.publicKeyBase64 should be public key base 64 encoded', async () => {
// tslint:disable-next-line:no-unused-expression
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',
})
);
});
tap.test('.sshKeys should point to an array of sshKeys', async () => {
let sshKeyArray = testSshInstance.sshKeys;
expect(sshKeyArray).toBeInstanceOf(Array);
expect(sshKeyArray[0].host).toEqual('gitlab.com');
expect(sshKeyArray[1].host).toEqual('bitbucket.org');
expect(sshKeyArray[2].host).toEqual('github.com');
});
tap.test('.getKey() should get a specific key selected by host', async () => {
expect(testSshInstance.getKey('github.com').pubKey).toEqual('someGitHubPublicKey');
});
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
View File

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

View File

@ -1,3 +1,6 @@
/// <reference path="./typings/main.d.ts" />
import plugins = require("./smartssh.plugins");
import classes = require("./smartssh.classes");
import * as plugins from './smartssh.plugins.js';
export { SshInstance } from './smartssh.classes.sshinstance.js';
export { SshKey } from './smartssh.classes.sshkey.js';
export { SshDir } from './smartssh.classes.sshdir.js';
export { SshConfig } from './smartssh.classes.sshconfig.js';

View File

@ -1,8 +1,7 @@
/// <reference path="./typings/main.d.ts" />
import plugins = require("./smartssh.plugins");
import classes = require("./smartssh.classes");
import * as plugins from './smartssh.plugins.js';
import { SshKey } from './smartssh.classes.sshkey.js';
export let sshKeyArrayFromDir = function(dirArg:string):classes.sshKey[]{
let sshKeyArray = [];
return sshKeyArray;
}
export let sshKeyArrayFromDir = function (dirArg: string): SshKey[] {
let sshKeyArray = []; // TODO
return sshKeyArray;
};

View File

@ -0,0 +1,60 @@
import * as plugins from './smartssh.plugins.js';
import * as helpers from './smartssh.classes.helpers.js';
import { SshKey } from './smartssh.classes.sshkey.js';
export class SshConfig {
private _sshKeyArray: SshKey[];
constructor(sshKeyArrayArg: SshKey[]) {
this._sshKeyArray = sshKeyArrayArg;
}
/**
* stores a config file
*/
store(dirPathArg: string) {
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[];
plugins.smartfile.fs.toStringSync(plugins.path.join(dirPathArg, 'config'));
return done.promise;
}
}
export interface configObject {
configString: string;
authorized: boolean;
sshKey: SshKey;
}

View File

@ -0,0 +1,47 @@
import * as plugins from './smartssh.plugins.js';
import * as helpers from './smartssh.classes.helpers.js';
import { SshInstance } from './smartssh.classes.sshinstance.js';
import { SshKey } from './smartssh.classes.sshkey.js';
import { SshConfig } from './smartssh.classes.sshconfig.js';
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(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);
}
/**
* 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

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

View File

@ -0,0 +1,106 @@
import * as plugins from './smartssh.plugins.js';
import * as helpers from './smartssh.classes.helpers.js';
export class SshKey {
private _privKey: string;
private _pubKey: string;
private _hostVar: string;
private _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._pubKey = optionsArg.public;
this._hostVar = optionsArg.host;
this._authorized = optionsArg.authorized;
}
// this.host
get host() {
return this._hostVar;
}
set host(hostArg: string) {
this._hostVar = hostArg;
}
// this.privKey
get privKey() {
return this._privKey;
}
set privKey(privateKeyArg: string) {
this._privKey = privateKeyArg;
}
// this.privKeyBase64
get privKeyBase64() {
return plugins.smartstring.base64.encode(this._privKey);
}
set privKeyBase64(privateKeyArg: string) {
this._privKey = plugins.smartstring.base64.decode(privateKeyArg);
}
// this.pubKey
get pubKey() {
return this._pubKey;
}
set pubKey(publicKeyArg: string) {
this._pubKey = publicKeyArg;
}
// this.pubKeyBase64
get pubKeyBase64() {
return plugins.smartstring.base64.encode(this._pubKey);
}
set pubKeyBase64(publicKeyArg: string) {
this._pubKey = plugins.smartstring.base64.decode(publicKeyArg);
}
get authorized() {
return this._authorized;
}
set authorized(authorizedArg: boolean) {
this._authorized = authorizedArg;
}
/**
* returns wether there is a private, a public or both keys
*/
get type() {
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 autocomputed.');
}
// methods
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}`);
}
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}`);
}
}
}

View File

@ -1,78 +0,0 @@
/// <reference path="./typings/main.d.ts" />
import plugins = require("./smartssh.plugins");
import helpers = require("./smartssh.classes.helpers");
export class ssh {
private sshDir:string;
private sshKeys:sshKey[];
private sshSync:boolean; // if set to true, the ssh dir will be kept in sync automatically
constructor(optionsArg:{sshDir?:string,sshSync?:boolean}={}){
this.sshDir = optionsArg.sshDir
this.sshDir ?
this.sshKeys = helpers.sshKeyArrayFromDir(this.sshDir)
: void(0);
this.sshSync = optionsArg.sshSync;
};
}
export class sshConfig {
constructor(){
}
}
export class sshKey {
private privKey:string;
private pubKey:string;
constructor(optionsArg:{private:string,public:string}){
if(!optionsArg) optionsArg = {private:undefined,public:undefined};
this.privKey = optionsArg.private;
this.pubKey = optionsArg.public;
};
// getters
get privateKey(){
return this.privKey;
};
get privateKeyBase64(){
return plugins.base64.encode(this.privKey);
}
get publicKey(){
return this.publicKey;
}
get publicKeyBase64(){
return plugins.base64.encode(this.pubKey);
}
get type(){
if(this.privKey && this.pubKey){
return "duplex";
} else if(this.privKey){
return "private";
} else if(this.pubKey){
return "public";
}
};
// setters
set privateKey(privateKeyArg:string){
this.privKey = privateKeyArg;
};
// setters
set publicKey(publicKeyArg:string){
this.pubKey = publicKeyArg;
};
store(filePathArg?:string){
let filePathObj = plugins.path.parse(filePathArg);
if(filePathObj.ext = ".priv"){
plugins.smartfile.memory.toFsSync(this.privKey,{fileName:filePathObj.name + filePathObj.ext,filePath:filePathObj.dir});
} else if (filePathObj.ext = ".pub"){
plugins.smartfile.memory.toFsSync(this.pubKey,{fileName:filePathObj.name + filePathObj.ext,filePath:filePathObj.dir});
} 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.priv")); // call this function recursivly
}
}
}

View File

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

View File

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

10
tsconfig.json Normal file
View File

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