working new account
This commit is contained in:
parent
2b2a0021aa
commit
2b9fadf4b4
|
@ -7,81 +7,83 @@ curl -s --user 'api:YOUR_API_KEY' \
|
||||||
-F subject='Hello' \
|
-F subject='Hello' \
|
||||||
-F text='Testing some Mailgun awesomeness!'
|
-F text='Testing some Mailgun awesomeness!'
|
||||||
*/
|
*/
|
||||||
|
var _auths = module.exports._auths = {};
|
||||||
module.exports.authenticate = function (opts) {
|
module.exports.authenticate = function (opts) {
|
||||||
|
console.log("It's auth'n time!");
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var requestAsync = util.promisify(require('request'));
|
var requestAsync = util.promisify(require('request'));
|
||||||
var state = opts.state;
|
var state = opts.state;
|
||||||
var jwtoken = opts.auth;
|
var jwtoken = opts.auth;
|
||||||
|
var auth;
|
||||||
var mailer = {
|
var mailer = {
|
||||||
user: 'wizard@telebit.cloud'
|
user: 'wizard@telebit.cloud'
|
||||||
, secret: 'fbbf21d73c9d2f480bd0e71f5f18494e'
|
, secret: 'fbbf21d73c9d2f480bd0e71f5f18494e'
|
||||||
};
|
};
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
if (!state._auths) {
|
|
||||||
state._auths = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('{' === jwtoken) {
|
console.log('[DEBUG] ext auth', jwtoken);
|
||||||
try {
|
auth = jwtoken;
|
||||||
auth = JSON.parse(auth);
|
if ('object' === typeof auth && /^.+@.+\..+$/.test(auth.subject)) {
|
||||||
} catch(e) {
|
console.log('parsed');
|
||||||
auth = null;
|
var id = crypto.randomBytes(16).toString('hex');
|
||||||
}
|
console.log("[DEBUG] gonna send email");
|
||||||
if (auth && /^.+@.+\..+$.test(auth.subject)) {
|
return requestAsync({
|
||||||
var id = crypto.randomBytes(16).toString('hex');
|
url: 'https://api.mailgun.net/v3/telebit.cloud/messages'
|
||||||
state._auths[id] = {};
|
, method: 'POST'
|
||||||
return requestAsync({
|
, auth: { user: 'api', pass: 'key-70ef48178081df19783ecfbe6fed5e9a' }
|
||||||
url: 'https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages'
|
, formData: {
|
||||||
, method: 'POST'
|
from: 'Telebit Wizard <wizard@telebit.cloud>'
|
||||||
, auth: { user: 'api', pass: 'key-70ef48178081df19783ecfbe6fed5e9a' }
|
, to: auth.subject
|
||||||
, formData: {
|
, subject: 'Telebit: Magic Link Login'
|
||||||
from: 'Telebit Wizard <wizard@telebit.cloud>'
|
, text: "Here's your magic login link. Just click to confirm your login attempt:\n\n"
|
||||||
, to: auth.subject
|
+ ' https://www.telebit.cloud/login/?magic=' + id + '\n\n'
|
||||||
, subject: 'Telebit: Magic Link Login'
|
+ "The login request came from '" + auth.hostname + "'\n "
|
||||||
, text: "Here's your magic login link. Just click to confirm your login attempt:\n\n"
|
+ "(" + auth.os_arch + " " + auth.os_platform + " " + auth.os_release + ")\n"
|
||||||
+ ' https://www.telebit.cloud/login/?magic=' + id + '\n\n'
|
}
|
||||||
+ "The login request came from '" + auth.hostname + "'\n "
|
}).then(function (resp) {
|
||||||
+ "(" + auth.os_arch + " " + auth.os_platform + " " + auth.os_release + ")\n"
|
console.log("[DEBUG] email was sent, or so they say");
|
||||||
}
|
console.log(resp.body);
|
||||||
}).then(function () {
|
return new state.Promise(function (resolve, reject) {
|
||||||
console.log("[DEBUG] email was sent, or so they say");
|
// TODO use global interval whenever the number of active links is high
|
||||||
return new state.Promise(function (resolve, reject) {
|
var t = setTimeout(function () {
|
||||||
// TODO use global interval whenever the number of active links is high
|
console.log("the moon lady wins :-/");
|
||||||
var t = setTimeout(function () {
|
delete _auths[id];
|
||||||
delete state._auths[id];
|
var err = new Error("Login Failure: Magic Link was not clicked within 5 minutes");
|
||||||
var err = new Error("Login Failure: Magic Link was not clicked within 5 minutes");
|
err.code = 'E_LOGIN_TIMEOUT';
|
||||||
err.code = 'E_LOGIN_TIMEOUT';
|
reject();
|
||||||
reject();
|
}, 300 * 1000);
|
||||||
}, 300 * 1000);
|
|
||||||
|
|
||||||
function authorize() {
|
function authorize() {
|
||||||
clearTimeout(t);
|
console.log("mighty auth'n ranger!");
|
||||||
delete state._auths[id];
|
clearTimeout(t);
|
||||||
var hri = require('human-readable-ids').hri;
|
delete _auths[id];
|
||||||
var hrname = hri.random() + '.telebit.cloud';
|
var hri = require('human-readable-ids').hri;
|
||||||
var jwt = require('jsonwebtoken');
|
var hrname = hri.random() + '.telebit.cloud';
|
||||||
var tokenData = {
|
var jwt = require('jsonwebtoken');
|
||||||
domains: [ hrname ]
|
var tokenData = {
|
||||||
, ports: [ 1024 + Math.round(Math.random() * 6300) ]
|
domains: [ hrname ]
|
||||||
, aud: 'telebit.cloud'
|
, ports: [ 1024 + Math.round(Math.random() * 6300) ]
|
||||||
, iss: Math.round(Date.now() / 1000)
|
, aud: 'telebit.cloud'
|
||||||
, id: id
|
, iss: Math.round(Date.now() / 1000)
|
||||||
};
|
, id: id
|
||||||
tokenData.jwt = jwt.sign(tokenData, state.secret);
|
, hostname: auth.hostname
|
||||||
resolve(tokenData);
|
|
||||||
}
|
|
||||||
|
|
||||||
state._auths[id] = {
|
|
||||||
fn: authorize
|
|
||||||
, dt: Date.now()
|
|
||||||
, reject: reject
|
|
||||||
};
|
};
|
||||||
|
tokenData.jwt = jwt.sign(tokenData, state.secret);
|
||||||
|
resolve(tokenData);
|
||||||
|
return tokenData;
|
||||||
|
}
|
||||||
|
|
||||||
|
_auths[id] = {
|
||||||
|
dt: Date.now()
|
||||||
|
, resolve: authorize
|
||||||
|
, reject: reject
|
||||||
|
};
|
||||||
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("just trying a normal token...");
|
||||||
try {
|
try {
|
||||||
decoded = jwt.decode(jwtoken, { complete: true });
|
decoded = jwt.decode(jwtoken, { complete: true });
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -90,3 +92,22 @@ module.exports.authenticate = function (opts) {
|
||||||
|
|
||||||
return state.defaults.authenticate(opts.auth);
|
return state.defaults.authenticate(opts.auth);
|
||||||
};
|
};
|
||||||
|
var express = require('express');
|
||||||
|
var app = express();
|
||||||
|
app.use('/login', function (req, res) {
|
||||||
|
var tokenData;
|
||||||
|
var magic = req.query.magic;
|
||||||
|
if (_auths[magic]) {
|
||||||
|
tokenData = _auths[magic].resolve();
|
||||||
|
res.send("<h1>Your device is authorized for the following:</h1><pre><code>" + JSON.stringify(tokenData, null, 2) + "</code></pre>");
|
||||||
|
} else {
|
||||||
|
res.send("<h1>Invalid Magic Link</h1>"
|
||||||
|
+ "<pre><code>'" + magic + "' isn't a valid link.\nLinks are only good for 5 minutes, so act fast.\n"
|
||||||
|
+ "(" + new Date(1000*((_auths[magic]||{}).dt||0)).toISOString() + ")</code></pre>\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
module.exports.webadmin = function (state, req, res) {
|
||||||
|
console.log('[DEBUG] extensions webadmin');
|
||||||
|
app(req, res);
|
||||||
|
};
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bluebird": "^3.5.1",
|
"bluebird": "^3.5.1",
|
||||||
"cluster-store": "^2.0.8",
|
"cluster-store": "^2.0.8",
|
||||||
|
"express": "^4.16.3",
|
||||||
"finalhandler": "^1.1.1",
|
"finalhandler": "^1.1.1",
|
||||||
"greenlock": "^2.2.4",
|
"greenlock": "^2.2.4",
|
||||||
"human-readable-ids": "^1.0.4",
|
"human-readable-ids": "^1.0.4",
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
"proxy-packer": "^1.4.3",
|
"proxy-packer": "^1.4.3",
|
||||||
"recase": "^1.0.4",
|
"recase": "^1.0.4",
|
||||||
"redirect-https": "^1.1.5",
|
"redirect-https": "^1.1.5",
|
||||||
|
"request": "^2.87.0",
|
||||||
"serve-static": "^1.13.2",
|
"serve-static": "^1.13.2",
|
||||||
"sni": "^1.0.0",
|
"sni": "^1.0.0",
|
||||||
"ws": "^5.1.1"
|
"ws": "^5.1.1"
|
||||||
|
|
Loading…
Reference in New Issue