set workers to -1
[xtuple] / node-datasource / routes / generate_oauth_key.js
1 /*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
2 regexp:true, undef:true, strict:true, trailing:true, white:true */
3 /*global X:true, _:true, SYS:true */
4
5 // https://localhost/dev/oauth/generate-key?id=7
6
7 (function () {
8   "use strict";
9
10   var exec = require("child_process").exec,
11     forge = require("node-forge"),
12     spawn = require("child_process").spawn,
13     async = require("async"),
14     path = require("path"),
15     fs = require("fs");
16
17   /**
18     Fetch the requested oauth2client model, validate the request,
19     generate a keypair whose public key will be saved with the
20     model and whose private key is returned to the browser.
21    */
22   exports.generateKey = function (req, res) {
23     var clientModel = new SYS.Oauth2client(),
24       id = req.query.id,
25       // generic error function for both the fetch and the save
26       error = function (model, err) {
27         console.log("oauth2client error ", arguments);
28         res.send({isError: true, error: err});
29       },
30       genKey = function (model, result) {
31         forge.pki.rsa.generateKeyPair({bits: 2048, workers: -1}, function (err, keypair) {
32           if (err) {
33             res.send({isError: true, message: "Error generating keypair: " + err.message, error: err});
34             return;
35           }
36
37           fetchSuccess(model, result, keypair);
38         });
39       },
40       sendP12 = function (keys) {
41         // It's possible and much easier to generate the p12 file without a
42         // cert. This example shows how to generate a cert if we actually need
43         // to, but OAuth is working without.
44         // @see: https://github.com/digitalbazaar/forge/blob/master/tests/nodejs-create-pkcs12.js#L11
45         //var p12Asn1 = forge.pkcs12.toPkcs12Asn1(keys.privateKey, [cert], 'notasecret'),
46         var p12Asn1 = forge.pkcs12.toPkcs12Asn1(keys.privateKey, null, 'notasecret'),
47           p12Der = forge.asn1.toDer(p12Asn1).getBytes(),
48           buffer = new Buffer(p12Der, 'binary');
49
50         res.attachment(clientModel.get('clientName') + '.p12');
51         res.send(new Buffer(buffer, 'base64'));
52       },
53       fetchSuccess = function (model, result, keys) {
54         var publicKey = forge.pki.publicKeyToPem(keys.publicKey),
55           saveSuccess = function (model, result) {
56             sendP12(keys);
57           };
58
59         // Cursory validation: this should be a jwt bearer and the
60         // public key field should not have already been set.
61         if (clientModel.get("clientType" !== "jwt bearer") ||
62             clientModel.get("clientX509PubCert")) {
63           res.send({isError: true, message: "Invalid request"});
64           return;
65         }
66
67         clientModel.set("clientX509PubCert", publicKey);
68         clientModel.save(null, {
69           error: error,
70           username: req.session.passport.user.username,
71           database: req.session.passport.user.organization,
72           success: saveSuccess
73         });
74       };
75
76     clientModel.fetch({
77       id: id,
78       username: req.session.passport.user.username,
79       database: req.session.passport.user.organization,
80       error: error,
81       success: genKey
82     });
83
84   };
85 }());