2017-01-31 21:56:09 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Copyright 2016 Realm Inc.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2016-10-20 00:55:46 +00:00
|
|
|
'use strict';
|
|
|
|
|
2016-11-08 16:59:30 +00:00
|
|
|
const AuthError = require('./errors').AuthError;
|
|
|
|
|
2016-10-20 00:55:46 +00:00
|
|
|
function node_require(module) {
|
|
|
|
return require(module);
|
|
|
|
}
|
|
|
|
|
2017-01-31 13:07:29 +00:00
|
|
|
const performFetch = typeof fetch === 'undefined' ? node_require('node-fetch') : fetch;
|
2016-10-20 00:55:46 +00:00
|
|
|
|
2017-01-31 21:56:09 +00:00
|
|
|
const url_parse = require('url-parse');
|
2016-10-20 00:55:46 +00:00
|
|
|
|
|
|
|
const postHeaders = {
|
|
|
|
'content-type': 'application/json;charset=utf-8',
|
|
|
|
'accept': 'application/json'
|
|
|
|
};
|
|
|
|
|
2016-11-08 16:59:30 +00:00
|
|
|
function auth_url(server) {
|
|
|
|
if (server.charAt(server.length-1) != '/') {
|
|
|
|
return server + '/auth';
|
|
|
|
}
|
|
|
|
return server + 'auth';
|
|
|
|
}
|
|
|
|
|
2017-01-31 13:07:29 +00:00
|
|
|
function authenticateRealm(user, fileUrl, realmUrl, callback) {
|
|
|
|
var url = auth_url(user.server);
|
|
|
|
var options = {
|
|
|
|
method: 'POST',
|
|
|
|
body: JSON.stringify({
|
|
|
|
data: user.token,
|
|
|
|
path: url_parse(realmUrl).pathname,
|
|
|
|
provider: 'realm',
|
|
|
|
app_id: ''
|
|
|
|
}),
|
|
|
|
headers: postHeaders
|
|
|
|
};
|
|
|
|
performFetch(url, options, function(error, response, body) {
|
|
|
|
if (error) {
|
|
|
|
callback(error);
|
|
|
|
}
|
|
|
|
else if (response.statusCode != 200) {
|
|
|
|
callback(new AuthError('Bad response: ' + response.statusCode));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// TODO: validate JSON
|
|
|
|
|
|
|
|
callback(undefined, {
|
|
|
|
token: body.access_token.token,
|
|
|
|
file_url: url_parse(fileUrl).pathname,
|
|
|
|
resolved_realm_url: 'realm://' + url_parse(realmUrl).host + body.access_token.token_data.path
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-01-31 21:56:09 +00:00
|
|
|
function _authenticate(userConstructor, server, json, callback) {
|
|
|
|
json.app_id = '';
|
|
|
|
const url = auth_url(server);
|
|
|
|
const options = {
|
|
|
|
method: 'POST',
|
|
|
|
body: JSON.stringify(json),
|
|
|
|
headers: postHeaders,
|
|
|
|
open_timeout: 5000
|
|
|
|
};
|
|
|
|
performFetch(url, options)
|
|
|
|
.then((response) => {
|
|
|
|
if (response.status !== 200) {
|
|
|
|
return response.json().then((body) => callback(new AuthError(body)));
|
|
|
|
} else {
|
|
|
|
return response.json().then(function (body) {
|
|
|
|
// TODO: validate JSON
|
|
|
|
const token = body.refresh_token.token;
|
|
|
|
const identity = body.refresh_token.token_data.identity;
|
|
|
|
callback(undefined, userConstructor.createUser(server, identity, token, false));
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(callback);
|
|
|
|
}
|
2016-10-20 00:55:46 +00:00
|
|
|
|
2017-01-31 21:56:09 +00:00
|
|
|
module.exports = {
|
|
|
|
static: {
|
|
|
|
get current() {
|
|
|
|
const allUsers = this.all;
|
2017-01-31 13:07:29 +00:00
|
|
|
const keys = Object.keys(allUsers);
|
|
|
|
if (keys.length === 0) {
|
|
|
|
return undefined;
|
|
|
|
} else if (keys.length > 1) {
|
|
|
|
throw new Error("Multiple users are logged in");
|
|
|
|
}
|
|
|
|
|
|
|
|
return allUsers[keys[0]];
|
2017-01-31 21:56:09 +00:00
|
|
|
},
|
2017-01-31 13:07:29 +00:00
|
|
|
|
2017-01-31 21:56:09 +00:00
|
|
|
adminUser(token) {
|
|
|
|
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
|
|
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
|
|
|
return v.toString(16);
|
|
|
|
});
|
|
|
|
var user = this.createUser('', uuid, token, true);
|
|
|
|
return user;
|
|
|
|
},
|
|
|
|
|
|
|
|
register(server, username, password, callback) {
|
|
|
|
_authenticate(this, server, {
|
|
|
|
provider: 'password',
|
|
|
|
user_info: { password: password, register: true },
|
|
|
|
data: username
|
|
|
|
}, callback);
|
|
|
|
},
|
|
|
|
|
|
|
|
login(server, username, password, callback) {
|
|
|
|
_authenticate(this, server, {
|
|
|
|
provider: 'password',
|
|
|
|
user_info: { password: password },
|
|
|
|
data: username
|
|
|
|
}, callback);
|
|
|
|
},
|
|
|
|
|
|
|
|
registerWithProvider(server, provider, providerToken, callback) {
|
|
|
|
_authenticate(this, server, {
|
|
|
|
provider: provider,
|
|
|
|
data: providerToken
|
|
|
|
}, callback);
|
|
|
|
},
|
|
|
|
|
|
|
|
_authenticateRealm: authenticateRealm
|
|
|
|
},
|
|
|
|
instance: {
|
|
|
|
openManagementRealm() {
|
|
|
|
let url = url_parse(this.server);
|
|
|
|
if (url.protocol === 'http:') {
|
|
|
|
url.set('protocol', 'realm:');
|
|
|
|
} else if (url.protocol === 'https:') {
|
|
|
|
url.set('protocol', 'realms:');
|
|
|
|
} else {
|
|
|
|
throw new Error(`Unexpected user auth url: ${this.server}`);
|
|
|
|
}
|
2017-01-31 13:07:29 +00:00
|
|
|
|
2017-01-31 21:56:09 +00:00
|
|
|
url.set('pathname', '/~/__management');
|
|
|
|
|
|
|
|
const realmConstructor = require('./index');
|
|
|
|
return new realmConstructor({
|
|
|
|
schema: require('./management-schema'),
|
|
|
|
sync: {
|
|
|
|
user: this,
|
|
|
|
url: url.href
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|