ssh.js 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.SSHKeyClient = exports.validatePrivateKey = exports.parsePublicKey = exports.parsePublicKeyFile = exports.getGeneratedPrivateKeyPath = exports.ERROR_SSH_INVALID_PRIVKEY = exports.ERROR_SSH_INVALID_PUBKEY = exports.ERROR_SSH_MISSING_PRIVKEY = void 0;
  4. const tslib_1 = require("tslib");
  5. const utils_fs_1 = require("@ionic/utils-fs");
  6. const os = tslib_1.__importStar(require("os"));
  7. const path = tslib_1.__importStar(require("path"));
  8. const guards_1 = require("../guards");
  9. const http_1 = require("./http");
  10. exports.ERROR_SSH_MISSING_PRIVKEY = 'SSH_MISSING_PRIVKEY';
  11. exports.ERROR_SSH_INVALID_PUBKEY = 'SSH_INVALID_PUBKEY';
  12. exports.ERROR_SSH_INVALID_PRIVKEY = 'SSH_INVALID_PRIVKEY';
  13. async function getGeneratedPrivateKeyPath(userId = 0) {
  14. return path.resolve(os.homedir(), '.ssh', 'ionic', String(userId));
  15. }
  16. exports.getGeneratedPrivateKeyPath = getGeneratedPrivateKeyPath;
  17. async function parsePublicKeyFile(pubkeyPath) {
  18. return parsePublicKey((await (0, utils_fs_1.readFile)(pubkeyPath, { encoding: 'utf8' })).trim());
  19. }
  20. exports.parsePublicKeyFile = parsePublicKeyFile;
  21. /**
  22. * @return [full pubkey, algorithm, public numbers, annotation]
  23. */
  24. function parsePublicKey(pubkey) {
  25. const r = /^(ssh-[A-z0-9]+)\s([A-z0-9+\/=]+)\s?(.+)?$/.exec(pubkey);
  26. if (!r) {
  27. throw exports.ERROR_SSH_INVALID_PUBKEY;
  28. }
  29. if (!r[3]) {
  30. r[3] = '';
  31. }
  32. r[1] = r[1].trim();
  33. r[2] = r[2].trim();
  34. r[3] = r[3].trim();
  35. return [pubkey, r[1], r[2], r[3]];
  36. }
  37. exports.parsePublicKey = parsePublicKey;
  38. async function validatePrivateKey(keyPath) {
  39. try {
  40. await (0, utils_fs_1.stat)(keyPath);
  41. }
  42. catch (e) {
  43. if (e.code === 'ENOENT') {
  44. throw exports.ERROR_SSH_MISSING_PRIVKEY;
  45. }
  46. throw e;
  47. }
  48. const f = await (0, utils_fs_1.readFile)(keyPath, { encoding: 'utf8' });
  49. const lines = f.split('\n');
  50. if (!lines[0].match(/^\-{5}BEGIN [A-Z]+ PRIVATE KEY\-{5}$/)) {
  51. throw exports.ERROR_SSH_INVALID_PRIVKEY;
  52. }
  53. }
  54. exports.validatePrivateKey = validatePrivateKey;
  55. class SSHKeyClient extends http_1.ResourceClient {
  56. constructor({ client, token, user }) {
  57. super();
  58. this.client = client;
  59. this.token = token;
  60. this.user = user;
  61. }
  62. async create({ pubkey }) {
  63. const { req } = await this.client.make('POST', `/users/${this.user.id}/sshkeys`);
  64. this.applyAuthentication(req, this.token);
  65. req.send({ pubkey });
  66. const res = await this.client.do(req);
  67. if (!(0, guards_1.isSSHKeyResponse)(res)) {
  68. throw (0, http_1.createFatalAPIFormat)(req, res);
  69. }
  70. return res.data;
  71. }
  72. async load(id) {
  73. const { req } = await this.client.make('GET', `/users/${this.user.id}/sshkeys/${id}`);
  74. this.applyAuthentication(req, this.token);
  75. const res = await this.client.do(req);
  76. if (!(0, guards_1.isSSHKeyResponse)(res)) {
  77. throw (0, http_1.createFatalAPIFormat)(req, res);
  78. }
  79. return res.data;
  80. }
  81. async delete(id) {
  82. const { req } = await this.client.make('DELETE', `/users/${this.user.id}/sshkeys/${id}`);
  83. this.applyAuthentication(req, this.token);
  84. await this.client.do(req);
  85. }
  86. paginate(args = {}) {
  87. return this.client.paginate({
  88. reqgen: async () => {
  89. const { req } = await this.client.make('GET', `/users/${this.user.id}/sshkeys`);
  90. this.applyAuthentication(req, this.token);
  91. return { req };
  92. },
  93. guard: guards_1.isSSHKeyListResponse,
  94. });
  95. }
  96. }
  97. exports.SSHKeyClient = SSHKeyClient;