now getting certificates

This commit is contained in:
Philipp Kunz 2017-01-02 00:18:51 +01:00
parent 96e0c4f905
commit 0056c8508c
12 changed files with 136 additions and 15 deletions

View File

@ -21,4 +21,16 @@ acme implementation in TypeScript
## Usage ## Usage
Use TypeScript for best in class instellisense. Use TypeScript for best in class instellisense.
```javascript
import { SmartAcme } from 'smartacme'
let smac = new SmartAcme()
let myAccount = smac.getAccount() // optionally accepts a filePath Arg with a stored acmeaccount.json
let myCert = myAccount.getChallenge('example.com','dns-01') // will return a dnsHash to set in your DNS record
myCert.get().then(() => {
console.log(myCert.certificate) // your certificate, ready to use in whatever way you prefer
})
```
[![npm](https://push.rocks/assets/repo-header.svg)](https://push.rocks) [![npm](https://push.rocks/assets/repo-header.svg)](https://push.rocks)

View File

1
dist/smartacme.classes.acmeaccount.js vendored Normal file
View File

@ -0,0 +1 @@
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuYWNtZWFjY291bnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuY2xhc3Nlcy5hY21lYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=

0
dist/smartacme.classes.acmecert.d.ts vendored Normal file
View File

1
dist/smartacme.classes.acmecert.js vendored Normal file
View File

@ -0,0 +1 @@
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuYWNtZWNlcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuY2xhc3Nlcy5hY21lY2VydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=

View File

@ -2,6 +2,7 @@
import 'typings-global'; import 'typings-global';
import * as q from 'q'; import * as q from 'q';
import { SmartacmeHelper, IRsaKeypair } from './smartacme.classes.helper'; import { SmartacmeHelper, IRsaKeypair } from './smartacme.classes.helper';
export declare type TChallenge = 'dns-01' | 'http-01';
/** /**
* class SmartAcme exports methods for maintaining SSL Certificates * class SmartAcme exports methods for maintaining SSL Certificates
*/ */
@ -25,7 +26,17 @@ export declare class SmartAcme {
createAccount(): q.Promise<{}>; createAccount(): q.Promise<{}>;
agreeTos(): q.Promise<{}>; agreeTos(): q.Promise<{}>;
/** /**
* requests a certificate * requests a challenge for a domain
* @param domainNameArg - the domain name to request a challenge for
* @param challengeType - the challenge type to request
*/ */
requestCertificate(domainNameArg: any): q.Promise<{}>; requestChallenge(domainNameArg: string, challengeTypeArg?: TChallenge): q.Promise<{}>;
/**
* getCertificate - takes care of cooldown, validation polling and certificate retrieval
*/
getCertificate(): void;
/**
* accept a challenge - for private use only
*/
private acceptChallenge(challenge);
} }

File diff suppressed because one or more lines are too long

View File

@ -28,11 +28,11 @@ describe('smartacme', function () {
done(); done();
}); });
}); });
it('should request a certifiacate for a domain', function (done) { it('should request a challenge for a domain', function (done) {
this.timeout(10000); this.timeout(10000);
testAcme.requestCertificate('bleu.de').then(() => { testAcme.requestChallenge('bleu.de').then(() => {
done(); done();
}); });
}); });
}); });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFFaEMsNEJBQTRCO0FBQzVCLDJDQUEwQztBQUUxQyxRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ2xCLElBQUksUUFBNkIsQ0FBQTtJQUVqQyxFQUFFLENBQUMsZ0NBQWdDLEVBQUU7UUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNuQixRQUFRLEdBQUcsSUFBSSxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUE7UUFDcEMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQ3ZELENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLDZCQUE2QixFQUFFO1FBQzlCLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDakQsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsK0JBQStCLEVBQUUsVUFBVSxJQUFJO1FBQzlDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxDQUFDLGFBQWEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzNCLElBQUksRUFBRSxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUc7WUFDUixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNiLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMscUJBQXFCLEVBQUUsVUFBUyxJQUFJO1FBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQztZQUNyQixJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsNENBQTRDLEVBQUUsVUFBUyxJQUFJO1FBQzFELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUN4QyxJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQSJ9 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFFaEMsNEJBQTRCO0FBQzVCLDJDQUEwQztBQUUxQyxRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ2xCLElBQUksUUFBNkIsQ0FBQTtJQUVqQyxFQUFFLENBQUMsZ0NBQWdDLEVBQUU7UUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNuQixRQUFRLEdBQUcsSUFBSSxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUE7UUFDcEMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQ3ZELENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLDZCQUE2QixFQUFFO1FBQzlCLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDakQsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsK0JBQStCLEVBQUUsVUFBVSxJQUFJO1FBQzlDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxDQUFDLGFBQWEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzNCLElBQUksRUFBRSxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUc7WUFDUixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNiLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMscUJBQXFCLEVBQUUsVUFBUyxJQUFJO1FBQ25DLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQztZQUNyQixJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMseUNBQXlDLEVBQUUsVUFBUyxJQUFJO1FBQ3ZELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUN0QyxJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQSJ9

View File

@ -34,9 +34,9 @@ describe('smartacme', function () {
}) })
}) })
it('should request a certifiacate for a domain', function(done) { it('should request a challenge for a domain', function(done) {
this.timeout(10000) this.timeout(10000)
testAcme.requestCertificate('bleu.de').then(() => { testAcme.requestChallenge('bleu.de').then(() => {
done() done()
}) })
}) })

View File

@ -0,0 +1,5 @@
import 'typings-global'
export class AcmeAccount {
}

View File

@ -0,0 +1,5 @@
import 'typings-global'
export class AcmeCert {
}

View File

@ -9,6 +9,9 @@ import * as paths from './smartacme.paths'
import { SmartacmeHelper, IRsaKeypair } from './smartacme.classes.helper' import { SmartacmeHelper, IRsaKeypair } from './smartacme.classes.helper'
export type TChallenge = 'dns-01' | 'http-01'
/** /**
* class SmartAcme exports methods for maintaining SSL Certificates * class SmartAcme exports methods for maintaining SSL Certificates
*/ */
@ -88,7 +91,7 @@ export class SmartAcme {
let tosPart = this.link.split(',')[1] let tosPart = this.link.split(',')[1]
let tosLinkPortion = tosPart.split(';')[0] let tosLinkPortion = tosPart.split(';')[0]
let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '') let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '')
this.rawacmeClient.post(this.location,{Agreement: url, resource: 'reg'}, (err, res) => { this.rawacmeClient.post(this.location, { Agreement: url, resource: 'reg' }, (err, res) => {
if (err) { if (err) {
console.log(err) console.log(err)
done.reject(err) done.reject(err)
@ -100,9 +103,11 @@ export class SmartAcme {
} }
/** /**
* requests a certificate * requests a challenge for a domain
* @param domainNameArg - the domain name to request a challenge for
* @param challengeType - the challenge type to request
*/ */
requestCertificate(domainNameArg) { requestChallenge(domainNameArg: string, challengeTypeArg: TChallenge = 'dns-01') {
let done = q.defer() let done = q.defer()
this.rawacmeClient.newAuthz( this.rawacmeClient.newAuthz(
{ {
@ -119,9 +124,55 @@ export class SmartAcme {
done.reject(err) done.reject(err)
} }
console.log(JSON.stringify(res.body)) console.log(JSON.stringify(res.body))
done.resolve() let dnsChallenge = res.body.challenges.filter(x => {
return x.type === challengeTypeArg
})[0]
this.acceptChallenge(dnsChallenge)
.then(x => {
done.resolve(x)
})
} }
) )
return done.promise return done.promise
} }
/**
* getCertificate - takes care of cooldown, validation polling and certificate retrieval
*/
getCertificate() {
}
/**
* accept a challenge - for private use only
*/
private acceptChallenge(challenge) {
let done = q.defer()
let authKey: string = rawacme.keyAuthz(challenge.token, this.keyPair.publicKey)
let dnsKeyHash: string = rawacme.dnsKeyAuthzHash(authKey) // needed if dns challenge is chosen
console.log(authKey)
this.rawacmeClient.post(
challenge.uri,
{
resource: 'challenge',
keyAuthorization: authKey
},
this.keyPair,
(err, res) => {
if (err) {
console.log(err)
done.reject(err)
}
console.log('acceptChallenge:')
console.log(JSON.stringify(res.body))
done.resolve(dnsKeyHash)
}
)
return done.promise
}
} }