fix(core): update
This commit is contained in:
parent
0faebf2a79
commit
62d27619f4
1046
package-lock.json
generated
1046
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -25,11 +25,16 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/umbrellazone/smartacme#README",
|
"homepage": "https://gitlab.com/umbrellazone/smartacme#README",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pushrocks/smartdata": "^3.1.2",
|
"@pushrocks/lik": "^3.0.4",
|
||||||
|
"@pushrocks/smartdata": "^3.1.13",
|
||||||
"@pushrocks/smartdelay": "^2.0.2",
|
"@pushrocks/smartdelay": "^2.0.2",
|
||||||
"@pushrocks/smartdns": "^3.0.8",
|
"@pushrocks/smartdns": "^3.0.8",
|
||||||
|
"@pushrocks/smartexpress": "^3.0.0",
|
||||||
"@pushrocks/smartpromise": "^2.0.5",
|
"@pushrocks/smartpromise": "^2.0.5",
|
||||||
"acme-client": "^2.2.1"
|
"@pushrocks/smartrequest": "^1.1.14",
|
||||||
|
"@pushrocks/smarttime": "^3.0.5",
|
||||||
|
"@pushrocks/smartunique": "^3.0.1",
|
||||||
|
"acme-client": "^2.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gitzone/tsbuild": "^2.1.4",
|
"@gitzone/tsbuild": "^2.1.4",
|
||||||
|
3
qenv.yml
3
qenv.yml
@ -1,3 +1,6 @@
|
|||||||
required:
|
required:
|
||||||
- CF_EMAIL
|
- CF_EMAIL
|
||||||
- CF_KEY
|
- CF_KEY
|
||||||
|
- MONGODB_URL
|
||||||
|
- MONGODB_PASSWORD
|
||||||
|
- MONGODB_DATABASE
|
||||||
|
16
test/test.ts
16
test/test.ts
@ -1,12 +1,14 @@
|
|||||||
import { tap, expect } from '@pushrocks/tapbundle';
|
import { tap, expect } from '@pushrocks/tapbundle';
|
||||||
|
import { Qenv } from '@pushrocks/qenv';
|
||||||
|
|
||||||
|
const testQenv = new Qenv('./', './.nogit/');
|
||||||
|
|
||||||
import * as smartacme from '../ts/index';
|
import * as smartacme from '../ts/index';
|
||||||
|
|
||||||
let smartAcmeInstance: smartacme.SmartAcme;
|
let smartAcmeInstance: smartacme.SmartAcme;
|
||||||
|
|
||||||
tap.test('should create a valid instance of SmartAcme', async () => {
|
tap.test('should create a valid instance of SmartAcme', async () => {
|
||||||
smartAcmeInstance = new smartacme.SmartAcme();
|
smartAcmeInstance = new smartacme.SmartAcme({
|
||||||
await smartAcmeInstance.init({
|
|
||||||
accountEmail: 'domains@lossless.org',
|
accountEmail: 'domains@lossless.org',
|
||||||
accountPrivateKey: null,
|
accountPrivateKey: null,
|
||||||
removeChallenge: async (...args) => {
|
removeChallenge: async (...args) => {
|
||||||
@ -14,9 +16,15 @@ tap.test('should create a valid instance of SmartAcme', async () => {
|
|||||||
},
|
},
|
||||||
setChallenge: async (...args) => {
|
setChallenge: async (...args) => {
|
||||||
console.log(args);
|
console.log(args);
|
||||||
}
|
},
|
||||||
|
mongoDescriptor: {
|
||||||
|
mongoDbName: testQenv.getEnvVarOnDemand('MONGODB_DATABASE'),
|
||||||
|
mongoDbPass: testQenv.getEnvVarOnDemand('MONGODB_PASSWORD'),
|
||||||
|
mongoDbUrl: testQenv.getEnvVarOnDemand('MONGODB_URL')
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// await smartAcmeInstance.getCertificateForDomain('bleu.de');
|
await smartAcmeInstance.init();
|
||||||
|
await smartAcmeInstance.getCertificateForDomain('bleu.de');
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.start();
|
tap.start();
|
||||||
|
@ -1 +1,3 @@
|
|||||||
export * from './smartacme.classes.smartacme';
|
export * from './smartacme.classes.smartacme';
|
||||||
|
|
||||||
|
export * from './smartacme.classes.certremoteclient';
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import * as plugins from './smartacme.plugins';
|
|
||||||
|
|
||||||
export class CertManager {
|
|
||||||
/**
|
|
||||||
* retrieves a certificate
|
|
||||||
*/
|
|
||||||
retrieveCertificate() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
34
ts/smartacme.classes.cert.ts
Normal file
34
ts/smartacme.classes.cert.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import * as plugins from './smartacme.plugins';
|
||||||
|
import { CertManager } from './smartacme.classes.certmanager';
|
||||||
|
|
||||||
|
import { Collection, svDb, unI } from '@pushrocks/smartdata';
|
||||||
|
|
||||||
|
@plugins.smartdata.Collection(() => {
|
||||||
|
return CertManager.activeDB;
|
||||||
|
})
|
||||||
|
export class Cert extends plugins.smartdata.SmartDataDbDoc<Cert> {
|
||||||
|
@unI()
|
||||||
|
public index: string;
|
||||||
|
|
||||||
|
@svDb()
|
||||||
|
domainName: string;
|
||||||
|
|
||||||
|
@svDb()
|
||||||
|
created: number;
|
||||||
|
|
||||||
|
@svDb()
|
||||||
|
privateKey: string;
|
||||||
|
|
||||||
|
@svDb()
|
||||||
|
publicKey: string;
|
||||||
|
|
||||||
|
@svDb()
|
||||||
|
csr: string;
|
||||||
|
|
||||||
|
constructor(privateKeyArg: string, publicKeyArg: string, csrArg: string) {
|
||||||
|
super();
|
||||||
|
this.privateKey = privateKeyArg;
|
||||||
|
this.publicKey = publicKeyArg;
|
||||||
|
this.csr = csrArg;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
import * as plugins from './smartacme.plugins';
|
|
||||||
|
|
||||||
export class SslCertificate {
|
|
||||||
privateKey: string;
|
|
||||||
publicKey: string;
|
|
||||||
csr: string;
|
|
||||||
}
|
|
67
ts/smartacme.classes.certmanager.ts
Normal file
67
ts/smartacme.classes.certmanager.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import * as plugins from './smartacme.plugins';
|
||||||
|
import { Cert } from './smartacme.classes.cert';
|
||||||
|
|
||||||
|
|
||||||
|
export class CertManager {
|
||||||
|
// =========
|
||||||
|
// STATIC
|
||||||
|
// =========
|
||||||
|
public static activeDB: plugins.smartdata.SmartdataDb;
|
||||||
|
|
||||||
|
|
||||||
|
// =========
|
||||||
|
// INSTANCE
|
||||||
|
// =========
|
||||||
|
private mongoDescriptor: plugins.smartdata.IMongoDescriptor;
|
||||||
|
public smartdataDb: plugins.smartdata.SmartdataDb;
|
||||||
|
|
||||||
|
constructor(optionsArg: {
|
||||||
|
mongoDescriptor: plugins.smartdata.IMongoDescriptor;
|
||||||
|
}) {
|
||||||
|
this.mongoDescriptor = optionsArg.mongoDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async init () {
|
||||||
|
this.smartdataDb = new plugins.smartdata.SmartdataDb(this.mongoDescriptor);
|
||||||
|
await this.smartdataDb.init();
|
||||||
|
CertManager.activeDB = this.smartdataDb;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves a certificate
|
||||||
|
* @returns the Cert class or null
|
||||||
|
* @param domainName the domain Name to retrieve the vcertificate for
|
||||||
|
*/
|
||||||
|
public async retrieveCertificate(domainName: string): Promise<Cert> {
|
||||||
|
const existingCertificate: Cert = await Cert.getInstance({
|
||||||
|
name: domainName
|
||||||
|
});
|
||||||
|
|
||||||
|
if(existingCertificate) {
|
||||||
|
return existingCertificate;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stores the certificate with the
|
||||||
|
* @param publicKeyArg
|
||||||
|
* @param privateKeyArg
|
||||||
|
* @param csrArg
|
||||||
|
*/
|
||||||
|
public async storeCertificate(privateKeyArg: string, publicKeyArg: string, csrArg: string) {
|
||||||
|
const cert = new Cert(privateKeyArg, publicKeyArg, csrArg);
|
||||||
|
cert.save();
|
||||||
|
};
|
||||||
|
|
||||||
|
public async deleteCertificate(domainName: string) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks all certs for expiration
|
||||||
|
*/
|
||||||
|
checkCerts() {}
|
||||||
|
}
|
10
ts/smartacme.classes.certremoteclient.ts
Normal file
10
ts/smartacme.classes.certremoteclient.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import * as plugins from './smartacme.plugins';
|
||||||
|
|
||||||
|
export class CertRemoteClient {
|
||||||
|
constructor(optionsArg: {
|
||||||
|
remoteUrl: string;
|
||||||
|
secret: string;
|
||||||
|
}) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
3
ts/smartacme.classes.certremotehandler.ts
Normal file
3
ts/smartacme.classes.certremotehandler.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import * as plugins from './smartacme.plugins';
|
||||||
|
|
||||||
|
export class CertRemoteHandler {}
|
@ -1,11 +1,21 @@
|
|||||||
import * as plugins from './smartacme.plugins';
|
import * as plugins from './smartacme.plugins';
|
||||||
|
import { CertManager } from './smartacme.classes.certmanager';
|
||||||
|
import { CertRemoteHandler } from './smartacme.classes.certremotehandler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export interface ISmartAcmeStorage {}
|
export interface ISmartAcmeOptions {
|
||||||
|
accountPrivateKey?: string;
|
||||||
|
accountEmail: string;
|
||||||
|
setChallenge: (domainName: string, keyAuthorization: string) => Promise<any>;
|
||||||
|
removeChallenge: (domainName: string) => Promise<any>;
|
||||||
|
mongoDescriptor: plugins.smartdata.IMongoDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
export class SmartAcme {
|
export class SmartAcme {
|
||||||
|
private options: ISmartAcmeOptions;
|
||||||
|
|
||||||
// the acme client
|
// the acme client
|
||||||
private client: any;
|
private client: any;
|
||||||
private smartdns = new plugins.smartdns.Smartdns();
|
private smartdns = new plugins.smartdns.Smartdns();
|
||||||
@ -17,15 +27,25 @@ export class SmartAcme {
|
|||||||
private setChallenge: (domainName: string, keyAuthorization: string) => Promise<any>;
|
private setChallenge: (domainName: string, keyAuthorization: string) => Promise<any>;
|
||||||
private removeChallenge: (domainName: string) => Promise<any>;
|
private removeChallenge: (domainName: string) => Promise<any>;
|
||||||
|
|
||||||
public async init(optionsArg: {
|
// certmanager
|
||||||
accountPrivateKey?: string;
|
private certmanager: CertManager;
|
||||||
accountEmail: string;
|
private certremoteHandler: CertRemoteHandler;
|
||||||
setChallenge: (domainName: string, keyAuthorization: string) => Promise<any>
|
|
||||||
removeChallenge: (domainName: string) => Promise<any>;
|
constructor(optionsArg: ISmartAcmeOptions) {
|
||||||
}) {
|
this.options = optionsArg;
|
||||||
this.privateKey = optionsArg.accountPrivateKey || (await plugins.acme.forge.createPrivateKey());
|
}
|
||||||
this.setChallenge = optionsArg.setChallenge;
|
|
||||||
this.removeChallenge = optionsArg.removeChallenge;
|
public async init() {
|
||||||
|
this.privateKey = this.options.accountPrivateKey || (await plugins.acme.forge.createPrivateKey());
|
||||||
|
this.setChallenge = this.options.setChallenge;
|
||||||
|
this.removeChallenge = this.options.removeChallenge;
|
||||||
|
|
||||||
|
this.certmanager = new CertManager({
|
||||||
|
mongoDescriptor: this.options.mongoDescriptor
|
||||||
|
});
|
||||||
|
await this.certmanager.init();
|
||||||
|
this.certremoteHandler = new CertRemoteHandler();
|
||||||
|
|
||||||
this.client = new plugins.acme.Client({
|
this.client = new plugins.acme.Client({
|
||||||
directoryUrl: plugins.acme.directory.letsencrypt.staging,
|
directoryUrl: plugins.acme.directory.letsencrypt.staging,
|
||||||
accountKey: this.privateKey
|
accountKey: this.privateKey
|
||||||
@ -34,13 +54,19 @@ export class SmartAcme {
|
|||||||
/* Register account */
|
/* Register account */
|
||||||
await this.client.createAccount({
|
await this.client.createAccount({
|
||||||
termsOfServiceAgreed: true,
|
termsOfServiceAgreed: true,
|
||||||
contact: [`mailto:${optionsArg.accountEmail}`]
|
contact: [`mailto:${this.options.accountEmail}`]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getCertificateForDomain(domainArg: string) {
|
public async getCertificateForDomain(domainArg: string) {
|
||||||
const domain = domainArg;
|
const domain = domainArg;
|
||||||
|
|
||||||
|
const retrievedCertificate = await this.certmanager.retrieveCertificate(domain);
|
||||||
|
|
||||||
|
if(retrievedCertificate) {
|
||||||
|
return retrievedCertificate;
|
||||||
|
}
|
||||||
|
|
||||||
/* Place new order */
|
/* Place new order */
|
||||||
const order = await this.client.createOrder({
|
const order = await this.client.createOrder({
|
||||||
identifiers: [{ type: 'dns', value: domain }, { type: 'dns', value: `*.${domain}` }]
|
identifiers: [{ type: 'dns', value: domain }, { type: 'dns', value: `*.${domain}` }]
|
||||||
@ -63,7 +89,6 @@ export class SmartAcme {
|
|||||||
await this.setChallenge(domainDnsName, keyAuthorization);
|
await this.setChallenge(domainDnsName, keyAuthorization);
|
||||||
await this.smartdns.checkUntilAvailable(domainDnsName, 'TXT', keyAuthorization, 100, 5000);
|
await this.smartdns.checkUntilAvailable(domainDnsName, 'TXT', keyAuthorization, 100, 5000);
|
||||||
|
|
||||||
|
|
||||||
/* Verify that challenge is satisfied */
|
/* Verify that challenge is satisfied */
|
||||||
await this.client.verifyChallenge(authz, dnsChallenge);
|
await this.client.verifyChallenge(authz, dnsChallenge);
|
||||||
|
|
||||||
@ -95,6 +120,8 @@ export class SmartAcme {
|
|||||||
console.log(`CSR:\n${csr.toString()}`);
|
console.log(`CSR:\n${csr.toString()}`);
|
||||||
console.log(`Private key:\n${key.toString()}`);
|
console.log(`Private key:\n${key.toString()}`);
|
||||||
console.log(`Certificate:\n${cert.toString()}`);
|
console.log(`Certificate:\n${cert.toString()}`);
|
||||||
|
|
||||||
|
this.certmanager.storeCertificate(key.toString(), cert.toString(), csr.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
toStorageObject() {}
|
toStorageObject() {}
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
// @pushrocks scope
|
// @pushrocks scope
|
||||||
|
import * as lik from '@pushrocks/lik';
|
||||||
|
import * as smartdata from '@pushrocks/smartdata';
|
||||||
import * as smartdelay from '@pushrocks/smartdelay';
|
import * as smartdelay from '@pushrocks/smartdelay';
|
||||||
import * as smartdns from '@pushrocks/smartdns';
|
import * as smartdns from '@pushrocks/smartdns';
|
||||||
|
import * as smartexpress from '@pushrocks/smartexpress';
|
||||||
import * as smartpromise from '@pushrocks/smartpromise';
|
import * as smartpromise from '@pushrocks/smartpromise';
|
||||||
|
import * as smartrequest from '@pushrocks/smartrequest';
|
||||||
|
import * as smartunique from '@pushrocks/smartunique';
|
||||||
|
import * as smarttime from '@pushrocks/smarttime';
|
||||||
|
|
||||||
export { smartdelay, smartdns, smartpromise };
|
export { lik, smartdata, smartdelay, smartdns, smartexpress, smartpromise, smartrequest, smartunique, smarttime };
|
||||||
|
|
||||||
// thirs party scope
|
// thirs party scope
|
||||||
import * as acme from 'acme-client';
|
import * as acme from 'acme-client';
|
||||||
|
7
tsconfig.json
Normal file
7
tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"target": "es2017",
|
||||||
|
"module": "commonjs"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user