UNPKG

3.97 kBJavaScriptView Raw
1'use strict'
2
3const WebIdTlsCertificate = require('../models/webid-tls-certificate')
4const debug = require('./../debug').accounts
5
6/**
7 * Represents an 'add new certificate to account' request
8 * (a POST to `/api/accounts/cert` endpoint).
9 *
10 * Note: The account has to exist, and the user must be already logged in,
11 * for this to succeed.
12 */
13class AddCertificateRequest {
14 /**
15 * @param [options={}] {Object}
16 * @param [options.accountManager] {AccountManager}
17 * @param [options.userAccount] {UserAccount}
18 * @param [options.certificate] {WebIdTlsCertificate}
19 * @param [options.response] {HttpResponse}
20 */
21 constructor (options) {
22 this.accountManager = options.accountManager
23 this.userAccount = options.userAccount
24 this.certificate = options.certificate
25 this.response = options.response
26 }
27
28 /**
29 * Handles the HTTP request (from an Express route handler).
30 *
31 * @param req
32 * @param res
33 * @param accountManager {AccountManager}
34 *
35 * @throws {TypeError}
36 * @throws {Error} HTTP 401 if the user is not logged in (`req.session.userId`
37 * does not match the intended account to which the cert is being added).
38 *
39 * @return {Promise}
40 */
41 static handle (req, res, accountManager) {
42 let request
43 try {
44 request = AddCertificateRequest.fromParams(req, res, accountManager)
45 } catch (error) {
46 return Promise.reject(error)
47 }
48
49 return AddCertificateRequest.addCertificate(request)
50 }
51
52 /**
53 * Factory method, returns an initialized instance of `AddCertificateRequest`.
54 *
55 * @param req
56 * @param res
57 * @param accountManager {AccountManager}
58 *
59 * @throws {TypeError} If required parameters missing
60 * @throws {Error} HTTP 401 if the user is not logged in (`req.session.userId`
61 * does not match the intended account to which the cert is being added).
62 *
63 * @return {AddCertificateRequest}
64 */
65 static fromParams (req, res, accountManager) {
66 let userAccount = accountManager.userAccountFrom(req.body)
67 let certificate = WebIdTlsCertificate.fromSpkacPost(
68 req.body.spkac,
69 userAccount,
70 accountManager.host)
71
72 debug(`Adding a new certificate for ${userAccount.webId}`)
73
74 if (req.session.userId !== userAccount.webId) {
75 debug(`Cannot add new certificate: signed in user is "${req.session.userId}"`)
76 let error = new Error("You are not logged in, so you can't create a certificate")
77 error.status = 401
78 throw error
79 }
80
81 let options = {
82 accountManager,
83 userAccount,
84 certificate,
85 response: res
86 }
87
88 return new AddCertificateRequest(options)
89 }
90
91 /**
92 * Generates a new certificate for a given user account, and adds it to that
93 * account's WebID Profile graph.
94 *
95 * @param request {AddCertificateRequest}
96 *
97 * @throws {Error} HTTP 400 if there were errors during certificate generation
98 *
99 * @returns {Promise}
100 */
101 static addCertificate (request) {
102 let { certificate, userAccount, accountManager } = request
103
104 return certificate.generateCertificate()
105 .catch(err => {
106 err.status = 400
107 err.message = 'Error generating a certificate: ' + err.message
108 throw err
109 })
110 .then(() => {
111 return accountManager.addCertKeyToProfile(certificate, userAccount)
112 })
113 .catch(err => {
114 err.status = 400
115 err.message = 'Error adding certificate to profile: ' + err.message
116 throw err
117 })
118 .then(() => {
119 request.sendResponse(certificate)
120 })
121 }
122
123 /**
124 * Sends the generated certificate in the response object.
125 *
126 * @param certificate {WebIdTlsCertificate}
127 */
128 sendResponse (certificate) {
129 let { response, userAccount } = this
130 response.set('User', userAccount.webId)
131 response.status(200)
132
133 response.set('Content-Type', 'application/x-x509-user-cert')
134 response.send(certificate.toDER())
135 }
136}
137
138module.exports = AddCertificateRequest