Skip to content

Commit b2ea526

Browse files
author
eden
committed
feat: support windows & mac os install and verify cerificate
0 parents  commit b2ea526

File tree

15 files changed

+7065
-0
lines changed

15 files changed

+7065
-0
lines changed

.commitlintrc.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
// 校验commit消息是否符合规范
3+
module.exports = {
4+
extends: ['@a8k/changelog', 'cz'],
5+
rules:{
6+
7+
}
8+
};

.eslintrc.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
env:
2+
commonjs: true
3+
es6: true
4+
node: true
5+
extends:
6+
- airbnb-base
7+
globals:
8+
Atomics: readonly
9+
SharedArrayBuffer: readonly
10+
parserOptions:
11+
ecmaVersion: 2018
12+
rules: {}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

.gitmessage

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
# run " npm i -g commitizen "
3+
# you can use " git cz " to commit message
4+
# example: git commit -m 'feat(all page): update components'
5+
# head: <type>(<scope>): <subject>
6+
# - type: feat, fix, refactor, docs, test, chore, style, revert
7+
# - scope: can be empty (eg. if the change is a global or difficult to assign to a single component)
8+
# - subject: start with verb (such as 'change'), 50-character line
9+
#
10+
# body: 72-character wrapped. This should answer:
11+
# * Why was this change necessary?
12+
# * How does it address the problem?
13+
# * Are there any side effects?
14+
#
15+
# footer:
16+
# - Include a link to the ticket, if any.
17+
# - BREAKING CHANGE
18+
#

.prettierrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
{
3+
"bracketSpacing": true,
4+
"singleQuote": true,
5+
"jsxBracketSameLine": false,
6+
"trailingComma": "es5",
7+
"tabWidth": 2,
8+
"semi": true,
9+
"printWidth": 120,
10+
"jsxSingleQuote": false,
11+
"arrowParens": "always"
12+
}

.stylelintrc.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
module.exports = {
3+
extends: [
4+
'stylelint-config-recommended',
5+
'stylelint-config-standard',
6+
'stylelint-config-css-modules',
7+
],
8+
plugins: ['stylelint-scss'],
9+
rules: {
10+
'at-rule-no-unknown': null,
11+
'scss/at-rule-no-unknown': true,
12+
},
13+
};

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# cert-helper
2+
3+
Install and trust certificates automatically. Very useful in the use of agent software scenarios.
4+
5+
## Usage
6+
7+
### install certificate
8+
9+
Install certification as root certificate
10+
11+
```js
12+
const { certInstaller } = require("cert-helper");
13+
certInstaller(path.resolve("./certs/root.crt"), err => {
14+
if (err) {
15+
//install error
16+
} else {
17+
//install success
18+
}
19+
});
20+
```
21+
22+
### verify certificate
23+
24+
Check certificate is installed
25+
26+
```js
27+
const { certVerify } = require("cert-helper");
28+
certVerify(
29+
{
30+
certDir: path.resolve("./certs/root.crt"),
31+
certName: "certificate name"
32+
},
33+
34+
err => {
35+
if (err) {
36+
console.info("Check cert failed!");
37+
} else {
38+
console.info("Check cert success!");
39+
}
40+
}
41+
);
42+
```

certs/root.crt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDvjCCAqagAwIBAgIBATANBgkqhkiG9w0BAQsFADBrMRAwDgYDVQQDEwdCaWZy
3+
b3N0MQswCQYDVQQGEwJDTjELMAkGA1UECBMCR0QxCzAJBgNVBAcTAlNaMR4wHAYD
4+
VQQKExViaWZyb3N0LmJ5dGVkYW5jZS5uZXQxEDAOBgNVBAsTB2JpZnJvc3QwHhcN
5+
MTgxMTIzMDUxODQ4WhcNMjkxMTIzMDUxODQ4WjBrMRAwDgYDVQQDEwdCaWZyb3N0
6+
MQswCQYDVQQGEwJDTjELMAkGA1UECBMCR0QxCzAJBgNVBAcTAlNaMR4wHAYDVQQK
7+
ExViaWZyb3N0LmJ5dGVkYW5jZS5uZXQxEDAOBgNVBAsTB2JpZnJvc3QwggEiMA0G
8+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCllAYrw75UNvXoUNpgyagB/JY2R5Re
9+
qtGgPBWDmMh2joAhzNuyOaqMAlSPZ5qzZbN8H9jrvd2eiOEspkn3GoOu+qYmlJkP
10+
U2GmKQy2zB9o6gQ/COwJpLsNFhpEG1c+hd8jOWxpltXCeFW8ko43OyVbjq3FUnRD
11+
NIm/3EhuQxO8UboIpsemm0+s0CsSjHnuiiG47Qlox5h/NDz9b9x2M2+KaqbdE/oj
12+
b0YNoRBpzAHH8sdF7lzZOZDWlL4yy6L54M374awtszRoeXNqzSWjUagtaDoMGcdo
13+
2PuHhI5U1vAafRjwN84XgLKkr7G41nBLjsBvAJjF7mtJR66MSyrDjdrTAgMBAAGj
14+
bTBrMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgL0MDsGA1UdJQQ0MDIGCCsGAQUF
15+
BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDARBglg
16+
hkgBhvhCAQEEBAMCAPcwDQYJKoZIhvcNAQELBQADggEBADNwE3hMr5BpBxO2v61m
17+
KurlpVLiZ17uOSHxXq59Y+6aujZlLVwHn4QEUAwsylOfOLQ9exxU7c7nJEBM3gRi
18+
RJtYkAs/Yhyv2C7IucP4VrT/3YSSUqtLD+s3McOt5BIHa/bvNUVZnply5yApgO7I
19+
9hAeLPPIAAijlao4tDQo4x6ko11fVFEFeSQyzPYSBcrheH++USRLNFV8llH/b/pS
20+
KYADVlq3CuAE/lyngkqM7u3mUy7PcRT6idlykd0EP8cUs6wsnPpBW6fHpBegWY/m
21+
uXTVzFD7p2xmyK2hAxngoiCwJbUcGjpPNcjTanFWeTScwe0E6hovhmS15tuqqehI
22+
Q50=
23+
-----END CERTIFICATE-----

lib/index.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* eslint-disable no-param-reassign */
2+
const path = require('path');
3+
const fs = require('fs');
4+
const mac = require('./mac');
5+
const windows = require('./windows');
6+
7+
/**
8+
*
9+
* @param {string} cert certificate file path
10+
* @param {Function} callback
11+
*/
12+
function install(cert, callback) {
13+
if (typeof cert !== 'string') {
14+
throw new Error('certificate file path must a string');
15+
}
16+
cert = path.resolve(cert);
17+
if (!fs.existsSync(cert)) {
18+
throw new Error(`${cert} file not found`);
19+
}
20+
21+
const { platform } = process;
22+
23+
if (platform === 'darwin') return mac.certInstaller(cert, callback);
24+
if (platform === 'win32') return windows.certInstaller(cert, callback);
25+
26+
throw new Error(`Platform ${platform} is not supported.`);
27+
}
28+
29+
/**
30+
* @typedef {Object} CertOptions
31+
* @property {string} certDir - certificate file path
32+
* @property {string} certName - certificate name
33+
*/
34+
35+
/**
36+
*
37+
* @param {CertOptions} cert
38+
* @param {Function} callback
39+
*/
40+
function verify(cert, callback) {
41+
const { certDir, certName } = cert;
42+
if (typeof certDir !== 'string') {
43+
throw new Error('cert.certDir path must a string');
44+
}
45+
if (typeof certName !== 'string') {
46+
throw new Error('cert.certName must a string');
47+
}
48+
cert.certDir = path.resolve(cert.certDir);
49+
50+
if (!fs.existsSync(cert.certDir)) {
51+
throw new Error(`${cert.certDir} file not found`);
52+
}
53+
54+
const { platform } = process;
55+
56+
if (platform === 'darwin') return mac.certVerify(cert, callback);
57+
if (platform === 'win32') return windows.certVerify(cert, callback);
58+
59+
throw new Error(`Platform ${platform} is not supported.`);
60+
}
61+
62+
module.exports = {
63+
certInstaller: install,
64+
certVerify: verify,
65+
};

lib/mac.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
const { spawn } = require('child_process');
2+
3+
function macVerify({ certDir }, callback) {
4+
const spawnVerify = spawn('security', ['verify-cert', '-c', certDir]);
5+
let errOutput;
6+
spawnVerify.on('error', (err) => callback(err));
7+
spawnVerify.stdout.on('data', (data) => {
8+
console.log('mac check cert', data.toString());
9+
});
10+
spawnVerify.stderr.on('data', (data) => {
11+
errOutput = data;
12+
});
13+
spawnVerify.on('close', (code) => {
14+
console.log('mac check cert code', code);
15+
if (code !== 0) return callback(new Error(errOutput));
16+
return callback(null);
17+
});
18+
}
19+
20+
function getDefaultKeychain(callback) {
21+
const spawnGetKeychain = spawn('security', ['default-keychain']);
22+
let errOutput;
23+
let keychain;
24+
spawnGetKeychain.on('error', (err) => callback(err));
25+
spawnGetKeychain.stdout.on('data', (data) => {
26+
console.log('mac get keychain', data.toString());
27+
// eslint-disable-next-line prefer-destructuring
28+
keychain = data.toString().split('"')[1];
29+
});
30+
spawnGetKeychain.stderr.on('data', (data) => {
31+
errOutput = data;
32+
});
33+
spawnGetKeychain.on('close', (code) => {
34+
console.log('mac get keychain code', code);
35+
if (code !== 0) return callback(new Error(errOutput));
36+
return callback(null, keychain);
37+
});
38+
}
39+
40+
function trustCert(keychain, cert, callback) {
41+
const spawnTrust = spawn('security', ['add-trusted-cert', '-k', keychain, cert]);
42+
let errOutput;
43+
spawnTrust.on('error', (err) => callback(err));
44+
spawnTrust.stdout.on('data', (data) => {
45+
console.log('mac install cert', data.toString());
46+
});
47+
spawnTrust.stderr.on('data', (data) => {
48+
errOutput = data;
49+
});
50+
spawnTrust.on('close', (code) => {
51+
console.log('mac install cert code', code);
52+
if (code !== 0) return callback(new Error(errOutput));
53+
return callback(null);
54+
});
55+
}
56+
57+
function verify(cert, callback) {
58+
return macVerify(cert, callback);
59+
}
60+
61+
function install(cert, callback) {
62+
getDefaultKeychain((err, keychain) => {
63+
if (err) return callback(err);
64+
65+
return trustCert(keychain, cert, callback);
66+
});
67+
}
68+
69+
module.exports = {
70+
certInstaller: install,
71+
certVerify: verify,
72+
};

0 commit comments

Comments
 (0)