generated from nginxinc/template-repository
-
Notifications
You must be signed in to change notification settings - Fork 11
/
examples.ts
120 lines (109 loc) · 3.39 KB
/
examples.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* ADDITIONAL EXAMPLES - Not required for the baseline implementation in
* `index.ts` but may be interesting to people who want to create their own
* implementations that may facilitate account creation or CSR generation.
*/
import { HttpClient } from './api'
import { LogLevel, Logger } from './logger'
import {
acmeAccountPrivateJWKPath,
acmeDirectoryURI,
acmeVerifyProviderHTTPS,
createCsr,
generateKey,
readOrCreateAccountKey,
toPEM,
} from './utils'
import { AcmeClient } from './client'
const log = new Logger()
/**
* Demonstrates how to use generate RSA Keys and use HttpClient
* @param r
* @returns
*/
async function acmeNewAccount(r: NginxHTTPRequest): Promise<void> {
// Generate a new RSA key pair for ACME account
const keys = (await generateKey()) as Required<CryptoKeyPair>
// Create a new ACME account
const client = new HttpClient(acmeDirectoryURI(r), keys.privateKey)
client.minLevel = LogLevel.Debug
client.setVerify(acmeVerifyProviderHTTPS(r))
// Get Terms Of Service link from the ACME provider
const tos = await client.getMetaField('termsOfService')
log.info(`termsOfService: ${tos}`)
// obtain a resource URL
const resourceUrl: string = await client.getResourceUrl('newAccount')
const payload = {
termsOfServiceAgreed: true,
contact: ['mailto:[email protected]'],
}
// Send a signed request
const sresp = await client.signedRequest(resourceUrl, payload)
const respO = {
headers: sresp.headers,
data: await sresp.json(),
status: sresp.status,
}
return r.return(200, JSON.stringify(respO))
}
/**
* Using AcmeClient to create a new account. It creates an account key if it doesn't exist
* @param {NginxHTTPRequest} r Incoming request
* @returns void
*/
async function clientNewAccount(r: NginxHTTPRequest): Promise<void> {
const accountKey = await readOrCreateAccountKey(acmeAccountPrivateJWKPath(r))
// Create a new ACME account
const client = new AcmeClient({
directoryUrl: acmeDirectoryURI(r),
accountKey: accountKey,
})
// display more logs
client.api.minLevel = LogLevel.Debug
// conditionally validate ACME provider cert
client.api.setVerify(acmeVerifyProviderHTTPS(r))
try {
const account = await client.createAccount({
termsOfServiceAgreed: true,
contact: ['mailto:[email protected]'],
})
return r.return(200, JSON.stringify(account))
} catch (e) {
const errMsg = `Error creating ACME account. Error=${e}`
log.error(errMsg)
return r.return(500, errMsg)
}
}
/**
* Create a new certificate Signing Request - Example implementation
* @param r
* @returns
*/
async function createCsrHandler(r: NginxHTTPRequest): Promise<void> {
const { pkcs10Ber, keys } = await createCsr({
// EXAMPLE VALUES BELOW
altNames: ['proxy1.f5.com', 'proxy2.f5.com'],
commonName: 'proxy.f5.com',
state: 'WA',
country: 'US',
organizationUnit: 'NGINX',
})
const privkey = (await crypto.subtle.exportKey(
'pkcs8',
keys.privateKey
)) as ArrayBuffer
const pubkey = (await crypto.subtle.exportKey(
'spki',
keys.publicKey
)) as ArrayBuffer
const privkeyPem = toPEM(privkey, 'PRIVATE KEY')
const pubkeyPem = toPEM(pubkey, 'PUBLIC KEY')
const csrPem = toPEM(pkcs10Ber, 'CERTIFICATE REQUEST')
const result = `${privkeyPem}\n${pubkeyPem}\n${csrPem}`
return r.return(200, result)
}
export default {
acmeNewAccount,
clientNewAccount,
createCsrHandler,
}