@mongodb-js/signing-utils 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,30 @@
1
1
  /// <reference types="node" />
2
2
  export { LocalSigningClient } from './local-signing-client';
3
3
  export { RemoteSigningClient } from './remote-signing-client';
4
- export type SigningMethod = 'gpg' | 'jsign';
4
+ export type SigningOptions = {
5
+ method: 'gpg';
6
+ } | {
7
+ method: 'jsign';
8
+ certificateAlias: 'compass' | 'mongosh';
9
+ timestampUrl?: string;
10
+ };
5
11
  export type SigningClientOptions = {
6
12
  workingDirectory: string;
7
13
  signingScript: string;
8
- signingMethod: SigningMethod;
14
+ signingOptions: SigningOptions;
9
15
  };
10
16
  export type RemoteSigningOptions = {
17
+ host?: string;
11
18
  username?: string;
12
19
  password?: string;
13
20
  port?: number;
14
21
  privateKey?: Buffer | string;
15
- signingMethod: SigningMethod;
22
+ signingOptions: SigningOptions;
16
23
  workingDirectory?: string;
17
24
  client: 'remote';
18
25
  };
19
26
  export type LocalSigningOptions = {
20
- signingMethod: SigningMethod;
27
+ signingOptions: SigningOptions;
21
28
  client: 'local';
22
29
  };
23
30
  export type ClientOptions = RemoteSigningOptions | LocalSigningOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signing-clients/index.ts"],"names":[],"mappings":";AAOA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,OAAO,CAAC;AAE5C,MAAM,MAAM,oBAAoB,GAAG;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;CAC9B,CAAC;AAGF,MAAM,MAAM,oBAAoB,GAAG;IAEjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE7B,aAAa,EAAE,aAAa,CAAC;IAK7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC;AAGF,MAAM,MAAM,mBAAmB,GAAG;IAEhC,aAAa,EAAE,aAAa,CAAC;IAE7B,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAEvE,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,aAAa,CAAC,CA2BxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signing-clients/index.ts"],"names":[],"mappings":";AAOA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,MAAM,cAAc,GACtB;IACE,MAAM,EAAE,KAAK,CAAC;CACf,GACD;IACE,MAAM,EAAE,OAAO,CAAC;IAEhB,gBAAgB,EAAE,SAAS,GAAG,SAAS,CAAC;IAExC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEN,MAAM,MAAM,oBAAoB,GAAG;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,cAAc,CAAC;CAChC,CAAC;AAGF,MAAM,MAAM,oBAAoB,GAAG;IAEjC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE7B,cAAc,EAAE,cAAc,CAAC;IAI/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC;AAGF,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAEvE,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,aAAa,CAAC,CA2BxB"}
@@ -44,13 +44,13 @@ async function getSigningClient(options) {
44
44
  return new remote_signing_client_1.RemoteSigningClient(sshClient, {
45
45
  workingDirectory: options.workingDirectory ?? '/home/ubuntu/garasign',
46
46
  signingScript,
47
- signingMethod: options.signingMethod,
47
+ signingOptions: options.signingOptions,
48
48
  });
49
49
  }
50
50
  if (options.client === 'local') {
51
51
  return new local_signing_client_1.LocalSigningClient({
52
52
  signingScript,
53
- signingMethod: options.signingMethod,
53
+ signingOptions: options.signingOptions,
54
54
  });
55
55
  }
56
56
  throw new Error(`Unknown client type: ${options.client}`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signing-clients/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,2CAA6B;AAC7B,8CAA0C;AAC1C,iEAA4D;AAC5D,mEAA8D;AAE9D,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA;AAC3B,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AA4CrB,KAAK,UAAU,gBAAgB,CACpC,OAAsB;IAEtB,KAAK,UAAU,YAAY,CAAC,UAAyB;QACnD,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAE5E,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAE9C,OAAO,IAAI,2CAAmB,CAAC,SAAS,EAAE;YACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,uBAAuB;YACrE,aAAa;YACb,aAAa,EAAE,OAAO,CAAC,aAAa;SACrC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC/B,OAAO,IAAI,yCAAkB,CAAC;YAC5B,aAAa;YACb,aAAa,EAAE,OAAO,CAAC,aAAa;SACrC,CAAC,CAAC;IACL,CAAC;IAGD,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5D,CAAC;AA7BD,4CA6BC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signing-clients/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,2CAA6B;AAC7B,8CAA0C;AAC1C,iEAA4D;AAC5D,mEAA8D;AAE9D,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA;AAC3B,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAqDrB,KAAK,UAAU,gBAAgB,CACpC,OAAsB;IAEtB,KAAK,UAAU,YAAY,CAAC,UAAyB;QACnD,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAE5E,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAE9C,OAAO,IAAI,2CAAmB,CAAC,SAAS,EAAE;YACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,uBAAuB;YACrE,aAAa;YACb,cAAc,EAAE,OAAO,CAAC,cAAc;SACvC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC/B,OAAO,IAAI,yCAAkB,CAAC;YAC5B,aAAa;YACb,cAAc,EAAE,OAAO,CAAC,cAAc;SACvC,CAAC,CAAC;IACL,CAAC;IAGD,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5D,CAAC;AA7BD,4CA6BC"}
@@ -1 +1 @@
1
- {"version":3,"file":"local-signing-client.d.ts","sourceRoot":"","sources":["../../src/signing-clients/local-signing-client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,GAAG,CAAC;AAU7D,qBAAa,kBAAmB,YAAW,aAAa;IAEpD,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;IAGjE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAyBlC"}
1
+ {"version":3,"file":"local-signing-client.d.ts","sourceRoot":"","sources":["../../src/signing-clients/local-signing-client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,GAAG,CAAC;AAU7D,qBAAa,kBAAmB,YAAW,aAAa;IAEpD,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;IAM3D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAqCxC"}
@@ -12,21 +12,27 @@ class LocalSigningClient {
12
12
  constructor(options) {
13
13
  this.options = options;
14
14
  }
15
- sign(file) {
15
+ async sign(file) {
16
16
  localClientDebug(`Signing ${file}`);
17
17
  const directoryOfFileToSign = path_1.default.dirname(file);
18
18
  try {
19
19
  const env = {
20
20
  ...(0, utils_1.getEnv)(),
21
- method: this.options.signingMethod,
21
+ ...(0, utils_1.mapSigningOptionsForScript)(this.options.signingOptions),
22
22
  };
23
- (0, child_process_1.spawnSync)('bash', [this.options.signingScript, path_1.default.basename(file)], {
23
+ const { stdout, stderr, status } = (0, child_process_1.spawnSync)('bash', [this.options.signingScript, path_1.default.basename(file)], {
24
24
  cwd: directoryOfFileToSign,
25
25
  env,
26
26
  encoding: 'utf-8',
27
27
  });
28
+ localClientDebug({ stdout, stderr });
29
+ if (status !== 0) {
30
+ throw new Error(JSON.stringify({
31
+ stdout,
32
+ stderr,
33
+ }));
34
+ }
28
35
  localClientDebug(`Signed file ${file}`);
29
- return Promise.resolve();
30
36
  }
31
37
  catch (error) {
32
38
  localClientDebug({ error });
@@ -1 +1 @@
1
- {"version":3,"file":"local-signing-client.js","sourceRoot":"","sources":["../../src/signing-clients/local-signing-client.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,iDAA0C;AAC1C,oCAAyC;AAGzC,MAAM,gBAAgB,GAAG,aAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAQ5D,MAAa,kBAAkB;IAC7B,YACU,OAAuD;QAAvD,YAAO,GAAP,OAAO,CAAgD;IAC9D,CAAC;IAEJ,IAAI,CAAC,IAAY;QACf,gBAAgB,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QAEpC,MAAM,qBAAqB,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEjD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG;gBACV,GAAG,IAAA,cAAM,GAAE;gBACX,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;aACnC,CAAC;YAEF,IAAA,yBAAS,EAAC,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,cAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;gBACnE,GAAG,EAAE,qBAAqB;gBAC1B,GAAG;gBACH,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YAEH,gBAAgB,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;YAExC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF;AA9BD,gDA8BC"}
1
+ {"version":3,"file":"local-signing-client.js","sourceRoot":"","sources":["../../src/signing-clients/local-signing-client.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,iDAA0C;AAC1C,oCAAqE;AAGrE,MAAM,gBAAgB,GAAG,aAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAQ5D,MAAa,kBAAkB;IAC7B,YACU,OAAuD;QAAvD,YAAO,GAAP,OAAO,CAAgD;IAC9D,CAAC;IAKJ,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,gBAAgB,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QAEpC,MAAM,qBAAqB,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEjD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG;gBACV,GAAG,IAAA,cAAM,GAAE;gBACX,GAAG,IAAA,kCAA0B,EAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;aAC3D,CAAC;YAEF,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,yBAAS,EAC1C,MAAM,EACN,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,cAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EACjD;gBACE,GAAG,EAAE,qBAAqB;gBAC1B,GAAG;gBACH,QAAQ,EAAE,OAAO;aAClB,CACF,CAAC;YAEF,gBAAgB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAErC,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CACb,IAAI,CAAC,SAAS,CAAC;oBACb,MAAM;oBACN,MAAM;iBACP,CAAC,CACH,CAAC;YACJ,CAAC;YACD,gBAAgB,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5B,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF;AA7CD,gDA6CC"}
@@ -3,13 +3,9 @@ import type { SigningClient, SigningClientOptions } from '.';
3
3
  export declare class RemoteSigningClient implements SigningClient {
4
4
  private sshClient;
5
5
  private options;
6
- private sftpConnection;
7
6
  constructor(sshClient: SSHClient, options: SigningClientOptions);
8
7
  private init;
9
8
  private getRemoteFilePath;
10
- private copyFile;
11
- private downloadFile;
12
- private removeFile;
13
9
  private signRemoteFile;
14
10
  sign(file: string): Promise<void>;
15
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remote-signing-client.d.ts","sourceRoot":"","sources":["../../src/signing-clients/remote-signing-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,GAAG,CAAC;AAE7D,qBAAa,mBAAoB,YAAW,aAAa;IAIrD,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;IAJjB,OAAO,CAAC,cAAc,CAAe;gBAG3B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,oBAAoB;YASzB,IAAI;IAYlB,OAAO,CAAC,iBAAiB;YAMX,QAAQ;YAWR,YAAY;YAWZ,UAAU;YAWV,cAAc;IAyBtB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAsBxC"}
1
+ {"version":3,"file":"remote-signing-client.d.ts","sourceRoot":"","sources":["../../src/signing-clients/remote-signing-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,GAAG,CAAC;AAE7D,qBAAa,mBAAoB,YAAW,aAAa;IAErD,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;gBADP,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,oBAAoB;YASzB,IAAI;IAWlB,OAAO,CAAC,iBAAiB;YAMX,cAAc;IA8BtB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAsBxC"}
@@ -12,56 +12,26 @@ class RemoteSigningClient {
12
12
  this.options = options;
13
13
  }
14
14
  async init() {
15
- this.sftpConnection = await this.sshClient.getSftpConnection();
16
15
  await this.sshClient.exec(`mkdir -p ${this.options.workingDirectory}`);
17
16
  {
18
17
  const remoteScript = `${this.options.workingDirectory}/garasign.sh`;
19
- await this.copyFile(this.options.signingScript, remoteScript);
18
+ await this.sshClient.copyFile(this.options.signingScript, remoteScript);
20
19
  await this.sshClient.exec(`chmod +x ${remoteScript}`);
21
20
  }
22
21
  }
23
22
  getRemoteFilePath(file) {
24
23
  return `${this.options.workingDirectory}/temp-${Date.now()}-${path_1.default.basename(file)}`;
25
24
  }
26
- async copyFile(file, remotePath) {
27
- return new Promise((resolve, reject) => {
28
- this.sftpConnection.fastPut(file, remotePath, (err) => {
29
- if (err) {
30
- return reject(err);
31
- }
32
- return resolve();
33
- });
34
- });
35
- }
36
- async downloadFile(remotePath, file) {
37
- return new Promise((resolve, reject) => {
38
- this.sftpConnection.fastGet(remotePath, file, (err) => {
39
- if (err) {
40
- return reject(err);
41
- }
42
- return resolve();
43
- });
44
- });
45
- }
46
- async removeFile(remotePath) {
47
- return new Promise((resolve, reject) => {
48
- this.sftpConnection.unlink(remotePath, (err) => {
49
- if (err) {
50
- return reject(err);
51
- }
52
- return resolve();
53
- });
54
- });
55
- }
56
25
  async signRemoteFile(file) {
57
26
  const env = (0, utils_1.getEnv)();
27
+ const signingOptions = (0, utils_1.mapSigningOptionsForScript)(this.options.signingOptions);
58
28
  const cmds = [
59
29
  `cd '${this.options.workingDirectory}'`,
60
30
  `export garasign_username=${env.garasign_username}`,
61
31
  `export garasign_password=${env.garasign_password}`,
62
32
  `export artifactory_username=${env.artifactory_username}`,
63
33
  `export artifactory_password=${env.artifactory_password}`,
64
- `export method=${this.options.signingMethod}`,
34
+ ...Object.keys(signingOptions).map((k) => `export ${k}=${signingOptions[k]}`),
65
35
  `./garasign.sh '${file}'`,
66
36
  ];
67
37
  const command = cmds.join(' && ');
@@ -72,18 +42,18 @@ class RemoteSigningClient {
72
42
  const remotePath = this.getRemoteFilePath(file);
73
43
  try {
74
44
  await this.init();
75
- await this.copyFile(file, remotePath);
45
+ await this.sshClient.copyFile(file, remotePath);
76
46
  (0, utils_1.debug)(`SFTP: Copied file ${file} to ${remotePath}`);
77
47
  await this.signRemoteFile(path_1.default.basename(remotePath));
78
48
  (0, utils_1.debug)(`SFTP: Signed file ${file}`);
79
- await this.downloadFile(remotePath, file);
49
+ await this.sshClient.downloadFile(remotePath, file);
80
50
  (0, utils_1.debug)(`SFTP: Downloaded signed file to ${file}`);
81
51
  }
82
52
  catch (error) {
83
53
  (0, utils_1.debug)({ error });
84
54
  }
85
55
  finally {
86
- await this.removeFile(remotePath);
56
+ await this.sshClient.removeFile(remotePath);
87
57
  (0, utils_1.debug)(`SFTP: Removed remote file ${remotePath}`);
88
58
  this.sshClient.disconnect();
89
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remote-signing-client.js","sourceRoot":"","sources":["../../src/signing-clients/remote-signing-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remote-signing-client.js","sourceRoot":"","sources":["../../src/signing-clients/remote-signing-client.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ConnectConfig, SFTPWrapper } from 'ssh2';
1
+ import type { ConnectConfig } from 'ssh2';
2
2
  export declare class SSHClient {
3
3
  private sshClientOptions;
4
4
  private sshConnection;
@@ -9,6 +9,9 @@ export declare class SSHClient {
9
9
  connect(): Promise<void>;
10
10
  disconnect(): void;
11
11
  exec(command: string): Promise<string>;
12
- getSftpConnection(): Promise<SFTPWrapper>;
12
+ private getSftpConnection;
13
+ copyFile(file: string, remotePath: string): Promise<void>;
14
+ downloadFile(remotePath: string, file: string): Promise<void>;
15
+ removeFile(remotePath: string): Promise<void>;
13
16
  }
14
17
  //# sourceMappingURL=ssh-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssh-client.d.ts","sourceRoot":"","sources":["../src/ssh-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,aAAa,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAOtE,qBAAa,SAAS;IAMR,OAAO,CAAC,gBAAgB;IALpC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAc;IAErC,OAAO,CAAC,SAAS,CAAS;gBAEN,gBAAgB,EAAE,aAAa;IAKnD,mBAAmB;IAgBb,OAAO;IAgBb,UAAU;IAKJ,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BtC,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC;CAUhD"}
1
+ {"version":3,"file":"ssh-client.d.ts","sourceRoot":"","sources":["../src/ssh-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,aAAa,EAAe,MAAM,MAAM,CAAC;AAOtE,qBAAa,SAAS;IAMR,OAAO,CAAC,gBAAgB;IALpC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAc;IAErC,OAAO,CAAC,SAAS,CAAS;gBAEN,gBAAgB,EAAE,aAAa;IAKnD,mBAAmB;IAgBb,OAAO;IAgBb,UAAU;IAKJ,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YA0B9B,iBAAiB;IAWzB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzD,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ7D,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAIpD"}
@@ -75,6 +75,18 @@ class SSHClient {
75
75
  (await (0, util_1.promisify)(this.sshConnection.sftp.bind(this.sshConnection))());
76
76
  return this.sftpConnection;
77
77
  }
78
+ async copyFile(file, remotePath) {
79
+ const sftpConnection = await this.getSftpConnection();
80
+ return (0, util_1.promisify)(sftpConnection.fastPut.bind(sftpConnection))(file, remotePath);
81
+ }
82
+ async downloadFile(remotePath, file) {
83
+ const sftpConnection = await this.getSftpConnection();
84
+ return (0, util_1.promisify)(sftpConnection.fastGet.bind(sftpConnection))(remotePath, file);
85
+ }
86
+ async removeFile(remotePath) {
87
+ const sftpConnection = await this.getSftpConnection();
88
+ return (0, util_1.promisify)(sftpConnection.unlink.bind(sftpConnection))(remotePath);
89
+ }
78
90
  }
79
91
  exports.SSHClient = SSHClient;
80
92
  //# sourceMappingURL=ssh-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssh-client.js","sourceRoot":"","sources":["../src/ssh-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ssh-client.js","sourceRoot":"","sources":["../src/ssh-client.ts"],"names":[],"mappings":"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"}
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  /// <reference types="debug" />
2
+ import type { SigningOptions } from './signing-clients';
2
3
  export declare const debug: import("debug").Debugger;
3
4
  export declare function getEnv(): {
4
5
  garasign_username: string | undefined;
@@ -6,4 +7,17 @@ export declare function getEnv(): {
6
7
  artifactory_username: string | undefined;
7
8
  artifactory_password: string | undefined;
8
9
  };
10
+ export declare function mapSigningOptionsForScript(options: SigningOptions): {
11
+ method: "gpg";
12
+ alias?: undefined;
13
+ timestampUrl?: undefined;
14
+ } | {
15
+ method: "jsign";
16
+ alias: "compass" | "mongosh";
17
+ timestampUrl: string;
18
+ } | {
19
+ method?: undefined;
20
+ alias?: undefined;
21
+ timestampUrl?: undefined;
22
+ };
9
23
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AAEA,eAAO,MAAM,KAAK,0BAA2B,CAAC;AAE9C,wBAAgB,MAAM;;;;;EAgBrB"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,eAAO,MAAM,KAAK,0BAA2B,CAAC;AAE9C,wBAAgB,MAAM;;;;;EAgBrB;AAID,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,cAAc;;;;;;;;;;;;EAgBjE"}
package/dist/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getEnv = exports.debug = void 0;
3
+ exports.mapSigningOptionsForScript = exports.getEnv = exports.debug = void 0;
4
4
  const debug_1 = require("debug");
5
5
  exports.debug = (0, debug_1.debug)('signing-utils');
6
6
  function getEnv() {
@@ -16,4 +16,21 @@ function getEnv() {
16
16
  };
17
17
  }
18
18
  exports.getEnv = getEnv;
19
+ const DEFAULT_JSIGN_TIMESTAMP_URL = 'http://timestamp.digicert.com';
20
+ function mapSigningOptionsForScript(options) {
21
+ if (options.method === 'gpg') {
22
+ return {
23
+ method: options.method,
24
+ };
25
+ }
26
+ if (options.method === 'jsign') {
27
+ return {
28
+ method: options.method,
29
+ alias: options.certificateAlias,
30
+ timestampUrl: options.timestampUrl ?? DEFAULT_JSIGN_TIMESTAMP_URL,
31
+ };
32
+ }
33
+ return {};
34
+ }
35
+ exports.mapSigningOptionsForScript = mapSigningOptionsForScript;
19
36
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,iCAAyC;AAE5B,QAAA,KAAK,GAAG,IAAA,aAAO,EAAC,eAAe,CAAC,CAAC;AAE9C,SAAgB,MAAM;IACpB,MAAM,iBAAiB,GACrB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACvE,MAAM,iBAAiB,GACrB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACvE,MAAM,oBAAoB,GACxB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC7E,MAAM,oBAAoB,GACxB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAE7E,OAAO;QACL,iBAAiB;QACjB,iBAAiB;QACjB,oBAAoB;QACpB,oBAAoB;KACrB,CAAC;AACJ,CAAC;AAhBD,wBAgBC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAAA,iCAAyC;AAG5B,QAAA,KAAK,GAAG,IAAA,aAAO,EAAC,eAAe,CAAC,CAAC;AAE9C,SAAgB,MAAM;IACpB,MAAM,iBAAiB,GACrB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACvE,MAAM,iBAAiB,GACrB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACvE,MAAM,oBAAoB,GACxB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC7E,MAAM,oBAAoB,GACxB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAE7E,OAAO;QACL,iBAAiB;QACjB,iBAAiB;QACjB,oBAAoB;QACpB,oBAAoB;KACrB,CAAC;AACJ,CAAC;AAhBD,wBAgBC;AAED,MAAM,2BAA2B,GAAG,+BAA+B,CAAC;AAEpE,SAAgB,0BAA0B,CAAC,OAAuB;IAChE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,OAAO;YACL,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC/B,OAAO;YACL,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,KAAK,EAAE,OAAO,CAAC,gBAAgB;YAC/B,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,2BAA2B;SAClE,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAhBD,gEAgBC"}
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "email": "compass@mongodb.com"
14
14
  },
15
15
  "homepage": "https://github.com/mongodb-js/devtools-shared",
16
- "version": "0.2.0",
16
+ "version": "0.2.2",
17
17
  "repository": {
18
18
  "type": "git",
19
19
  "url": "https://github.com/mongodb-js/devtools-shared.git"
@@ -70,5 +70,5 @@
70
70
  "debug": "^4.3.4",
71
71
  "ssh2": "^1.15.0"
72
72
  },
73
- "gitHead": "ad497d997a5164646475261232687c8d0ace8722"
73
+ "gitHead": "eb7e757ac0ab44f343b22df168a26ebc1955eccc"
74
74
  }
package/src/garasign.sh CHANGED
@@ -1,5 +1,7 @@
1
1
  #! /usr/bin/env bash
2
2
 
3
+ set -e
4
+
3
5
  if [ -z "$1" ]; then
4
6
  echo "Usage: garasign.sh <file>"
5
7
  exit 1
@@ -22,13 +24,15 @@ trap logout_artifactory EXIT
22
24
  echo "Logging into docker artifactory"
23
25
  echo "${artifactory_password}" | docker login --password-stdin --username ${artifactory_username} ${ARTIFACTORY_HOST} > /dev/null 2>&1
24
26
 
25
- # If the docker login failed, exit
26
- [ $? -ne 0 ] && exit $?
27
+ if [ $? -ne 0 ]; then
28
+ echo "Docker login failed" >&2
29
+ exit 1
30
+ fi
27
31
 
28
32
  directory=$(pwd)
29
33
  file=$1
30
34
 
31
- echo "File to be signed: $file"
35
+ echo "File to be signed: $file using $method"
32
36
  echo "Working directory: $directory"
33
37
 
34
38
  gpg_sign() {
@@ -43,6 +47,9 @@ gpg_sign() {
43
47
  }
44
48
 
45
49
  jsign_sign() {
50
+ if [ -z ${alias+omitted} ]; then echo "Alias must be set when signing with jsign" && exit 1; fi
51
+ if [ -z ${timestampUrl+omitted} ]; then echo "Timestamp URL must be set when signing with jsign" && exit 1; fi
52
+
46
53
  docker run \
47
54
  -e GRS_CONFIG_USER1_USERNAME="${garasign_username}" \
48
55
  -e GRS_CONFIG_USER1_PASSWORD="${garasign_password}" \
@@ -50,13 +57,15 @@ jsign_sign() {
50
57
  -v $directory:$directory \
51
58
  -w $directory \
52
59
  artifactory.corp.mongodb.com/release-tools-container-registry-local/garasign-jsign \
53
- /bin/bash -c "jsign --tsaurl "timestamp.url" -a mongo-authenticode-2021 '$file'"
60
+ /bin/bash -c "jsign -t '$timestampUrl' -a '$alias' '$file'"
54
61
  }
55
62
 
56
- if [[ "$method" -eq "gpg" ]]; then
63
+ if [[ $method == "gpg" ]]; then
57
64
  gpg_sign
58
- elif [[ "$method" -eq "jsign" ]]; then
65
+ elif [[ $method == "jsign" ]]; then
59
66
  jsign_sign
67
+ else
68
+ echo "Unknown signing method: $method"
69
+ exit 1
60
70
  fi
61
-
62
71
  echo "Finished signing $file"
@@ -8,16 +8,28 @@ import { RemoteSigningClient } from './remote-signing-client';
8
8
  export { LocalSigningClient } from './local-signing-client';
9
9
  export { RemoteSigningClient } from './remote-signing-client';
10
10
 
11
- export type SigningMethod = 'gpg' | 'jsign';
11
+ export type SigningOptions =
12
+ | {
13
+ method: 'gpg';
14
+ }
15
+ | {
16
+ method: 'jsign';
17
+ // The alias of the certificate used for signing in the keystore
18
+ certificateAlias: 'compass' | 'mongosh';
19
+ // The URL of the timestamping authority.
20
+ timestampUrl?: string;
21
+ };
12
22
 
13
23
  export type SigningClientOptions = {
14
24
  workingDirectory: string;
15
25
  signingScript: string;
16
- signingMethod: SigningMethod;
26
+ signingOptions: SigningOptions;
17
27
  };
18
28
 
19
29
  /** Options for signing a file remotely over an SSH connection. */
20
30
  export type RemoteSigningOptions = {
31
+ /** Hostname or IP address of the server to */
32
+ host?: string;
21
33
  /** Username for authentication. */
22
34
  username?: string;
23
35
  /** Password for password-based user authentication. */
@@ -26,9 +38,8 @@ export type RemoteSigningOptions = {
26
38
  port?: number;
27
39
  /** Buffer or string that contains a private key for either key-based or hostbased user authentication (OpenSSH format). */
28
40
  privateKey?: Buffer | string;
29
- /** The method to sign with. Use gpg on linux and jsign on windows. */
30
- signingMethod: SigningMethod;
31
41
 
42
+ signingOptions: SigningOptions;
32
43
  /**
33
44
  * The path of the working directory in which to sign files **on the remote ssh server**. Defaults to `/home/ubuntu/garasign`.
34
45
  */
@@ -38,9 +49,7 @@ export type RemoteSigningOptions = {
38
49
 
39
50
  /** Options for signing a file locally. */
40
51
  export type LocalSigningOptions = {
41
- /** The method to sign with. Use gpg on linux and jsign on windows. */
42
- signingMethod: SigningMethod;
43
-
52
+ signingOptions: SigningOptions;
44
53
  client: 'local';
45
54
  };
46
55
 
@@ -67,13 +76,13 @@ export async function getSigningClient(
67
76
  return new RemoteSigningClient(sshClient, {
68
77
  workingDirectory: options.workingDirectory ?? '/home/ubuntu/garasign',
69
78
  signingScript,
70
- signingMethod: options.signingMethod,
79
+ signingOptions: options.signingOptions,
71
80
  });
72
81
  }
73
82
  if (options.client === 'local') {
74
83
  return new LocalSigningClient({
75
84
  signingScript,
76
- signingMethod: options.signingMethod,
85
+ signingOptions: options.signingOptions,
77
86
  });
78
87
  }
79
88
  // @ts-expect-error `client` is a discriminated union - we should never reach here but we throw on the off-chance we do.
@@ -31,7 +31,9 @@ describe('LocalSigningClient', function () {
31
31
  it('executes the signing script correctly', async function () {
32
32
  const localSigningClient = new LocalSigningClient({
33
33
  signingScript: signingScript,
34
- signingMethod: 'gpg',
34
+ signingOptions: {
35
+ method: 'gpg',
36
+ },
35
37
  });
36
38
 
37
39
  await localSigningClient.sign(fileToSign);
@@ -41,4 +43,46 @@ describe('LocalSigningClient', function () {
41
43
  ).trim();
42
44
  expect(signedFile).to.equal('signed content');
43
45
  });
46
+
47
+ context('when the script returns a non-zero exit code', function () {
48
+ beforeEach(function () {
49
+ writeFileSync(
50
+ signingScript,
51
+ `
52
+ #!/bin/bash
53
+ echo "Signing script called with arguments: $@"
54
+ >&2 echo "error - something went wrong"
55
+ exit 1
56
+ `
57
+ );
58
+ });
59
+
60
+ it('sign() rejects', async function () {
61
+ const localSigningClient = new LocalSigningClient({
62
+ signingScript: signingScript,
63
+ signingOptions: {
64
+ method: 'gpg',
65
+ },
66
+ });
67
+
68
+ const error = await localSigningClient.sign(fileToSign).catch((e) => e);
69
+ expect(error).to.be.instanceOf(Error);
70
+ });
71
+
72
+ it('includes the stdout and stderr of the failed script in the error', async function () {
73
+ const localSigningClient = new LocalSigningClient({
74
+ signingScript: signingScript,
75
+ signingOptions: {
76
+ method: 'gpg',
77
+ },
78
+ });
79
+
80
+ const error: Error = await localSigningClient
81
+ .sign(fileToSign)
82
+ .catch((e) => e);
83
+ const { stdout, stderr } = JSON.parse(error.message);
84
+ expect(stdout).to.contain('Signing script called with arguments: ');
85
+ expect(stderr).to.equal('error - something went wrong\n');
86
+ });
87
+ });
44
88
  });
@@ -1,6 +1,6 @@
1
1
  import path from 'path';
2
2
  import { spawnSync } from 'child_process';
3
- import { debug, getEnv } from '../utils';
3
+ import { debug, getEnv, mapSigningOptionsForScript } from '../utils';
4
4
  import type { SigningClient, SigningClientOptions } from '.';
5
5
 
6
6
  const localClientDebug = debug.extend('LocalSigningClient');
@@ -16,7 +16,10 @@ export class LocalSigningClient implements SigningClient {
16
16
  private options: Omit<SigningClientOptions, 'workingDirectory'>
17
17
  ) {}
18
18
 
19
- sign(file: string): Promise<void> {
19
+ // we want to wrap any errors in promise rejections, so even though there is no
20
+ // await statement, we use an `async` function
21
+ // eslint-disable-next-line @typescript-eslint/require-await
22
+ async sign(file: string): Promise<void> {
20
23
  localClientDebug(`Signing ${file}`);
21
24
 
22
25
  const directoryOfFileToSign = path.dirname(file);
@@ -24,18 +27,30 @@ export class LocalSigningClient implements SigningClient {
24
27
  try {
25
28
  const env = {
26
29
  ...getEnv(),
27
- method: this.options.signingMethod,
30
+ ...mapSigningOptionsForScript(this.options.signingOptions),
28
31
  };
29
32
 
30
- spawnSync('bash', [this.options.signingScript, path.basename(file)], {
31
- cwd: directoryOfFileToSign,
32
- env,
33
- encoding: 'utf-8',
34
- });
35
-
33
+ const { stdout, stderr, status } = spawnSync(
34
+ 'bash',
35
+ [this.options.signingScript, path.basename(file)],
36
+ {
37
+ cwd: directoryOfFileToSign,
38
+ env,
39
+ encoding: 'utf-8',
40
+ }
41
+ );
42
+
43
+ localClientDebug({ stdout, stderr });
44
+
45
+ if (status !== 0) {
46
+ throw new Error(
47
+ JSON.stringify({
48
+ stdout,
49
+ stderr,
50
+ })
51
+ );
52
+ }
36
53
  localClientDebug(`Signed file ${file}`);
37
-
38
- return Promise.resolve();
39
54
  } catch (error) {
40
55
  localClientDebug({ error });
41
56
  throw error;
@@ -3,55 +3,16 @@ import { exec } from 'child_process';
3
3
  import { RemoteSigningClient } from './remote-signing-client';
4
4
  import { expect } from 'chai';
5
5
  import type { SSHClient } from '../ssh-client';
6
+ import { promisify } from 'util';
6
7
 
7
8
  const getMockedSSHClient = () => {
8
9
  return {
9
- getSftpConnection: () => {
10
- return {
11
- fastPut: async (
12
- localFile: string,
13
- remoteFile: string,
14
- cb: (err?: Error) => void
15
- ) => {
16
- try {
17
- await fs.copyFile(localFile, remoteFile);
18
- cb();
19
- } catch (err) {
20
- cb(err as Error);
21
- }
22
- },
23
- fastGet: async (
24
- remoteFile: string,
25
- localFile: string,
26
- cb: (err?: Error) => void
27
- ) => {
28
- try {
29
- await fs.copyFile(remoteFile, localFile);
30
- cb();
31
- } catch (err) {
32
- cb(err as Error);
33
- }
34
- },
35
- unlink: async (remoteFile: string, cb: (err?: Error) => void) => {
36
- try {
37
- await fs.unlink(remoteFile);
38
- cb();
39
- } catch (err) {
40
- cb(err as Error);
41
- }
42
- },
43
- };
44
- },
45
- exec: (command: string) => {
46
- return new Promise((resolve, reject) => {
47
- exec(command, { shell: 'bash' }, (err) => {
48
- if (err) {
49
- return reject(err);
50
- }
51
- return resolve('Ok');
52
- });
53
- });
54
- },
10
+ // The mocked ssh client
11
+ copyFile: (from: string, to: string) => fs.copyFile(from, to),
12
+ downloadFile: (remote: string, local: string) => fs.copyFile(remote, local),
13
+ removeFile: fs.unlink.bind(fs.unlink),
14
+ exec: (command: string) =>
15
+ promisify(exec)(command, { shell: 'bash' }).then(() => 'Ok'),
55
16
  disconnect: () => {},
56
17
  } as unknown as SSHClient;
57
18
  };
@@ -85,7 +46,9 @@ describe('RemoteSigningClient', function () {
85
46
  const remoteSigningClient = new RemoteSigningClient(getMockedSSHClient(), {
86
47
  workingDirectory: workingDirectoryPath,
87
48
  signingScript: signingScript,
88
- signingMethod: 'gpg',
49
+ signingOptions: {
50
+ method: 'gpg',
51
+ },
89
52
  });
90
53
 
91
54
  await remoteSigningClient.sign(fileToSign);
@@ -1,12 +1,9 @@
1
1
  import path from 'path';
2
- import type { SFTPWrapper } from 'ssh2';
3
2
  import type { SSHClient } from '../ssh-client';
4
- import { debug, getEnv } from '../utils';
3
+ import { debug, getEnv, mapSigningOptionsForScript } from '../utils';
5
4
  import type { SigningClient, SigningClientOptions } from '.';
6
5
 
7
6
  export class RemoteSigningClient implements SigningClient {
8
- private sftpConnection!: SFTPWrapper;
9
-
10
7
  constructor(
11
8
  private sshClient: SSHClient,
12
9
  private options: SigningClientOptions
@@ -19,13 +16,12 @@ export class RemoteSigningClient implements SigningClient {
19
16
  * - Copy the signing script to the remote machine
20
17
  */
21
18
  private async init() {
22
- this.sftpConnection = await this.sshClient.getSftpConnection();
23
19
  await this.sshClient.exec(`mkdir -p ${this.options.workingDirectory}`);
24
20
 
25
21
  // Copy the signing script to the remote machine
26
22
  {
27
23
  const remoteScript = `${this.options.workingDirectory}/garasign.sh`;
28
- await this.copyFile(this.options.signingScript, remoteScript);
24
+ await this.sshClient.copyFile(this.options.signingScript, remoteScript);
29
25
  await this.sshClient.exec(`chmod +x ${remoteScript}`);
30
26
  }
31
27
  }
@@ -36,41 +32,11 @@ export class RemoteSigningClient implements SigningClient {
36
32
  )}`;
37
33
  }
38
34
 
39
- private async copyFile(file: string, remotePath: string): Promise<void> {
40
- return new Promise((resolve, reject) => {
41
- this.sftpConnection.fastPut(file, remotePath, (err) => {
42
- if (err) {
43
- return reject(err);
44
- }
45
- return resolve();
46
- });
47
- });
48
- }
49
-
50
- private async downloadFile(remotePath: string, file: string): Promise<void> {
51
- return new Promise((resolve, reject) => {
52
- this.sftpConnection.fastGet(remotePath, file, (err) => {
53
- if (err) {
54
- return reject(err);
55
- }
56
- return resolve();
57
- });
58
- });
59
- }
60
-
61
- private async removeFile(remotePath: string): Promise<void> {
62
- return new Promise((resolve, reject) => {
63
- this.sftpConnection.unlink(remotePath, (err) => {
64
- if (err) {
65
- return reject(err);
66
- }
67
- return resolve();
68
- });
69
- });
70
- }
71
-
72
35
  private async signRemoteFile(file: string) {
73
36
  const env = getEnv();
37
+ const signingOptions = mapSigningOptionsForScript(
38
+ this.options.signingOptions
39
+ );
74
40
  /**
75
41
  * Passing env variables as an option to ssh.exec() doesn't work as ssh config
76
42
  * (`sshd_config.AllowEnv`) does not allow to pass env variables by default.
@@ -86,7 +52,9 @@ export class RemoteSigningClient implements SigningClient {
86
52
  `export artifactory_username=${env.artifactory_username}`,
87
53
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
88
54
  `export artifactory_password=${env.artifactory_password}`,
89
- `export method=${this.options.signingMethod}`,
55
+ ...(Object.keys(signingOptions) as (keyof typeof signingOptions)[]).map(
56
+ (k) => `export ${k}=${signingOptions[k] as string}`
57
+ ),
90
58
  `./garasign.sh '${file}'`,
91
59
  ];
92
60
  const command = cmds.join(' && ');
@@ -100,18 +68,18 @@ export class RemoteSigningClient implements SigningClient {
100
68
  // establish connection
101
69
  await this.init();
102
70
 
103
- await this.copyFile(file, remotePath);
71
+ await this.sshClient.copyFile(file, remotePath);
104
72
  debug(`SFTP: Copied file ${file} to ${remotePath}`);
105
73
 
106
74
  await this.signRemoteFile(path.basename(remotePath));
107
75
  debug(`SFTP: Signed file ${file}`);
108
76
 
109
- await this.downloadFile(remotePath, file);
77
+ await this.sshClient.downloadFile(remotePath, file);
110
78
  debug(`SFTP: Downloaded signed file to ${file}`);
111
79
  } catch (error) {
112
80
  debug({ error });
113
81
  } finally {
114
- await this.removeFile(remotePath);
82
+ await this.sshClient.removeFile(remotePath);
115
83
  debug(`SFTP: Removed remote file ${remotePath}`);
116
84
  this.sshClient.disconnect();
117
85
  }
package/src/ssh-client.ts CHANGED
@@ -79,7 +79,7 @@ export class SSHClient {
79
79
  return data;
80
80
  }
81
81
 
82
- async getSftpConnection(): Promise<SFTPWrapper> {
82
+ private async getSftpConnection(): Promise<SFTPWrapper> {
83
83
  if (!this.connected) {
84
84
  throw new Error('Not connected to ssh server');
85
85
  }
@@ -89,4 +89,25 @@ export class SSHClient {
89
89
  (await promisify(this.sshConnection.sftp.bind(this.sshConnection))());
90
90
  return this.sftpConnection;
91
91
  }
92
+
93
+ async copyFile(file: string, remotePath: string): Promise<void> {
94
+ const sftpConnection = await this.getSftpConnection();
95
+ return promisify(sftpConnection.fastPut.bind(sftpConnection))(
96
+ file,
97
+ remotePath
98
+ );
99
+ }
100
+
101
+ async downloadFile(remotePath: string, file: string): Promise<void> {
102
+ const sftpConnection = await this.getSftpConnection();
103
+ return promisify(sftpConnection.fastGet.bind(sftpConnection))(
104
+ remotePath,
105
+ file
106
+ );
107
+ }
108
+
109
+ async removeFile(remotePath: string): Promise<void> {
110
+ const sftpConnection = await this.getSftpConnection();
111
+ return promisify(sftpConnection.unlink.bind(sftpConnection))(remotePath);
112
+ }
92
113
  }
package/src/utils.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { debug as debugFn } from 'debug';
2
+ import type { SigningOptions } from './signing-clients';
2
3
 
3
4
  export const debug = debugFn('signing-utils');
4
5
 
@@ -19,3 +20,23 @@ export function getEnv() {
19
20
  artifactory_password,
20
21
  };
21
22
  }
23
+
24
+ const DEFAULT_JSIGN_TIMESTAMP_URL = 'http://timestamp.digicert.com';
25
+
26
+ export function mapSigningOptionsForScript(options: SigningOptions) {
27
+ if (options.method === 'gpg') {
28
+ return {
29
+ method: options.method,
30
+ };
31
+ }
32
+
33
+ if (options.method === 'jsign') {
34
+ return {
35
+ method: options.method,
36
+ alias: options.certificateAlias,
37
+ timestampUrl: options.timestampUrl ?? DEFAULT_JSIGN_TIMESTAMP_URL,
38
+ };
39
+ }
40
+
41
+ return {};
42
+ }