docs/src/utils/HubUtil.js

191 lines
5.9 KiB
JavaScript

var _ = require('underscore');
var request = require('request');
var accountServerActions = require('../actions/AccountServerActions');
var metrics = require('./MetricsUtil');
let HUB2_ENDPOINT = process.env.HUB2_ENDPOINT || 'https://hub.docker.com/v2';
module.exports = {
init: function () {
accountServerActions.prompted({prompted: localStorage.getItem('auth.prompted')});
let username = localStorage.getItem('auth.username');
let verified = localStorage.getItem('auth.verified') === 'true';
if (username) {
accountServerActions.loggedin({username, verified});
}
},
username: function () {
return localStorage.getItem('auth.username') || null;
},
// Returns the base64 encoded index token or null if no token exists
config: function () {
let config = localStorage.getItem('auth.config');
if (!config) {
return null;
}
return config;
},
// Retrives the current jwt hub token or null if no token exists
jwt: function () {
let jwt = localStorage.getItem('auth.jwt');
if (!jwt) {
return null;
}
return jwt;
},
prompted: function () {
return localStorage.getItem('auth.prompted');
},
setPrompted: function (prompted) {
localStorage.setItem('auth.prompted', true);
accountServerActions.prompted({prompted});
},
request: function (req, callback) {
let jwt = this.jwt();
if (jwt) {
_.extend(req, {
headers: {
Authorization: `JWT ${jwt}`
}
});
}
// First attempt with existing JWT
request(req, (error, response, body) => {
let data = JSON.parse(body);
// If the JWT has expired, then log in again to get a new JWT
if (data && data.detail && data.detail.indexOf('expired') !== -1) {
let config = this.config();
if (!this.config()) {
this.logout();
return;
}
let [username, password] = this.creds(config);
this.auth(username, password, (error, response, body) => {
let data = JSON.parse(body);
if (response.statusCode === 200 && data && data.token) {
localStorage.setItem('auth.jwt', data.token);
} else {
this.logout();
}
this.request(req, callback);
});
} else {
callback(error, response, body);
}
});
},
loggedin: function () {
return this.jwt() && this.config();
},
logout: function () {
accountServerActions.loggedout();
localStorage.removeItem('auth.jwt');
localStorage.removeItem('auth.username');
localStorage.removeItem('auth.verified');
localStorage.removeItem('auth.config');
},
login: function (username, password, callback) {
this.auth(username, password, (error, response, body) => {
if (error) {
accountServerActions.errors({errors: {detail: error.message}});
callback(error);
return;
}
let data = JSON.parse(body);
if (response.statusCode === 200) {
if (data.token) {
localStorage.setItem('auth.jwt', data.token);
localStorage.setItem('auth.username', username);
localStorage.setItem('auth.verified', true);
localStorage.setItem('auth.config', new Buffer(username + ':' + password).toString('base64'));
accountServerActions.loggedin({username, verified: true});
accountServerActions.prompted({prompted: true});
metrics.track('Successfully Logged In');
if (callback) { callback(); }
require('./RegHubUtil').repos();
} else {
accountServerActions.errors({errors: {detail: 'Did not receive login token.'}});
if (callback) { callback(new Error('Did not receive login token.')); }
}
} else if (response.statusCode === 401) {
if (data && data.detail && data.detail.indexOf('Account not active yet') !== -1) {
accountServerActions.loggedin({username, verified: false});
accountServerActions.prompted({prompted: true});
localStorage.setItem('auth.username', username);
localStorage.setItem('auth.verified', false);
localStorage.setItem('auth.config', new Buffer(username + ':' + password).toString('base64'));
if (callback) { callback(); }
} else {
accountServerActions.errors({errors: data});
if (callback) { callback(new Error(data.detail)); }
}
}
});
},
auth: function (username, password, callback) {
request.post(`${HUB2_ENDPOINT}/users/login/`, {form: {username, password}}, (error, response, body) => {
callback(error, response, body);
});
},
verify: function () {
let config = this.config();
if (!config) {
this.logout();
return;
}
let [username, password] = this.creds(config);
this.login(username, password);
},
creds: function (config) {
return new Buffer(config, 'base64').toString().split(/:(.+)?/).slice(0, 2);
},
// Signs up and places a token under ~/.dockercfg and saves a jwt to localstore
signup: function (username, password, email, subscribe) {
request.post(`${HUB2_ENDPOINT}/users/signup/`, {
form: {
username,
password,
email,
subscribe
}
}, (err, response, body) => {
if (response.statusCode === 204) {
accountServerActions.signedup({username, verified: false});
accountServerActions.prompted({prompted: true});
localStorage.setItem('auth.username', username);
localStorage.setItem('auth.verified', false);
localStorage.setItem('auth.config', new Buffer(username + ':' + password).toString('base64'));
metrics.track('Successfully Signed Up');
} else {
let data = JSON.parse(body);
let errors = {};
for (let key in data) {
errors[key] = data[key][0];
}
accountServerActions.errors({errors});
}
});
},
};