From 88a093d5ba474baf5b1214a1b115504ef2ee32e4 Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Fri, 31 Aug 2018 02:37:29 +0200 Subject: [PATCH 1/9] Refactor user auth --- docs/sync.js | 127 ++++++---- lib/extensions.js | 2 + lib/index.d.ts | 36 ++- lib/user-methods.js | 280 ++++++++++------------ tests/js/admin-user-helper.js | 3 +- tests/js/download-api-helper.js | 10 +- tests/js/encryption-tests.js | 3 +- tests/js/nested-list-helper.js | 12 +- tests/js/object-id-tests.js | 5 +- tests/js/partial-sync-api-helper.js | 10 +- tests/js/permission-tests.js | 6 +- tests/js/session-tests.js | 76 +++--- tests/js/user-tests.js | 111 ++++----- tests/package-lock.json | 359 ++++++++++++++++++++++++++++ 14 files changed, 684 insertions(+), 356 deletions(-) create mode 100644 tests/package-lock.json diff --git a/docs/sync.js b/docs/sync.js index 1890a6d3a3..c642f81645 100644 --- a/docs/sync.js +++ b/docs/sync.js @@ -288,58 +288,105 @@ class IncompatibleSyncedRealmError { } /** - * Class for logging in and managing Sync users. + * Class for creating user credentials * @memberof Realm.Sync */ -class User { +class Credentials { /** - * Login a sync user with username and password. - * @param {string} server - authentication server - * @param {string} username - * @param {string} password - * @param {function(error, user)} [callback] - called with the following arguments: - * - `error` - an Error object is provided on failure - * - `user` - a valid User object on success - * @returns {void|Promise} Returns a promise with a user if the callback was not specified + * Creates credentials based on a login with a username and a password. + * @param {string} username The username of the user. + * @param {string} password The user's password. + * @param {boolean} createUser optional - `true` if the user should be created, `false` otherwise. If + * `true` is provided and the user exists, or `false` is provided and the user doesn't exist, + * an error will be thrown. If not specified, if the user doesn't exist, they will be created, + * otherwise, they'll be logged in if the password matches. + * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. */ - static login(server, username, password, callback) {} + static usernamePassword(username, password, createUser) {}; /** - * Authenticate a sync user with provider. - * @param {string} server - authentication server - * @param {string} provider - the provider (curently: 'password', and 'jwt') - * @param {object} options - options used by provider: - * - jwt - `token`; a JWT token - * - password - `username` and `password` - * @return {Promise} Returns a promise with a user + * Creates credentials based on a Facebook login. + * @param {string} token A Facebook authentication token, obtained by logging into Facebook.. + * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. */ - static authenticate(server, provider, options) {} + static facebook(token); /** - * Register/login a sync user using an external login provider. - * @param {string} server - authentication server - * @param {object} options - options, containing the following: - * @param {string} options.provider - The provider type - * @param {string} options.providerToken - The access token for the given provider - * @param {object} [options.userInfo] - A map containing additional data required by the provider - * @param {function(error, User)} [callback] - an optional callback called with the following arguments: - * - `error` - an Error object is provided on failure - * - `user` - a valid User object on success - * @return {void|Promise} Returns a promise with a user if the callback was not specified + * Creates credentials based on a Google login. + * @param {string} token A Google authentication token, obtained by logging into Google.. + * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + static google(token) {}; + + /** + * Creates credentials for an anonymous user. These can only be used once - using them a second + * time will result in a different user being logged in. If you need to get a user that has already logged + * in with the Anonymous credentials, use @see {User.current} or @see {User.all} + * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. */ - static registerWithProvider(server, options, callback) {} + static anonymous() {}; /** - * Register a sync user with username and password. - * @param {string} server - authentication server - * @param {string} username - * @param {string} password - * @param {function(error, user)} [callback] - called with the following arguments: - * - `error` - an Error object is provided on failure - * - `user` - a valid User object on success - * @return {void|Promise} Returns a promise with a user if the callback was not specified - */ - static register(server, username, password, callback) {} + * Creates credentials based on a login with a nickname. If multiple users try to login + * with the same nickname, they'll get the same underlying sync user. + * @param {string} value The nickname of the user. + * @param {boolean} isAdmin An optional parameter controlling whether the user is admin. + * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + */ + static nickname(value, isAdmin) {}; + + /** + * Creates credentials based on an Active Directory login. + * @param {string} token An access token, obtained by logging into Azure Active Directory. + * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + */ + static azureAD(token) {}; + + /** + * Creates credentials based on a JWT login. + * @param {string} token A Json Web Token, that will be validated against the server's configured rules. + * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + */ + static jwt(token) {}; + + /** + * Creates credentials based on an admin token. Using this credential will not contact the Realm Object Server. + * @param {string} token The admin token. + * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + */ + static adminToken(token) {}; + + /** + * Gets the identity provider for the credentials. + * @returns {string} The identity provider, such as Google, Facebook, etc. + */ + get provider(); + + /** + * Gets the access token. + * @returns {string} + */ + get token(); + + /** + * Gets additional user information associated with the credentials. + * @returns {object} A dictionary, containing the additional information. + */ + get userInfo(); + +} + +/** + * Class for logging in and managing Sync users. + * @memberof Realm.Sync + */ +class User { + /** + * Logs the user in to the Realm Object Server. + * @param {string} server The url of the server that the user is authenticated against. + * @param {Credentials} credentials The credentials to use for authentication. Obtain them by calling one of the + * @see {Credentials} static methods. + */ + static login(server, credentials) {} /** * Request a password reset email to be sent to a user's email. diff --git a/lib/extensions.js b/lib/extensions.js index 42af07b009..2950b91525 100644 --- a/lib/extensions.js +++ b/lib/extensions.js @@ -178,6 +178,8 @@ module.exports = function(realmConstructor) { Object.defineProperties(realmConstructor.Sync.User, getOwnPropertyDescriptors(userMethods.static)); Object.defineProperties(realmConstructor.Sync.User.prototype, getOwnPropertyDescriptors(userMethods.instance)); Object.defineProperty(realmConstructor.Sync.User, '_realmConstructor', { value: realmConstructor }); + realmConstructor.Sync.Credentials = {}; + Object.defineProperties(realmConstructor.Sync.Credentials, getOwnPropertyDescriptors(userMethods.credentials)); realmConstructor.Sync.AuthError = require('./errors').AuthError; diff --git a/lib/index.d.ts b/lib/index.d.ts index 2cc415d024..52e17bddf2 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -290,6 +290,21 @@ declare namespace Realm.Sync { isAdmin: boolean; } + class Credentials { + static usernamePassword(username: string, password: string, createUser?: boolean): Credentials; + static facebook(token: string): Credentials; + static google(token: string): Credentials; + static anonymous(): Credentials; + static nickname(value: string, isAdmin?: boolean): Credentials; + static azureAD(token: string): Credentials; + static jwt(token: string): Credentials; + static adminToken(token: string): Credentials; + + readonly provider: string; + readonly token: string; + readonly userInfo: { [key: string]: any }; + } + /** * User * @see { @link https://realm.io/docs/javascript/latest/api/Realm.Sync.User.html } @@ -302,26 +317,7 @@ declare namespace Realm.Sync { readonly isAdminToken: boolean; readonly server: string; readonly token: string; - static adminUser(adminToken: string, server?: string): User; - - /** - * @deprecated, to be removed in future versions - */ - static login(server: string, username: string, password: string, callback: (error: any, user: User) => void): void; - static login(server: string, username: string, password: string): Promise; - - /** - * @deprecated, to be removed in future versions - */ - static register(server: string, username: string, password: string, callback: (error: any, user: User) => void): void; - static register(server: string, username: string, password: string): Promise; - - /** - * @deprecated, to be removed in versions - */ - static registerWithProvider(server: string, options: { provider: string, providerToken: string, userInfo: any }, callback: (error: Error | null, user: User | null) => void): void; - static registerWithProvider(server: string, options: { provider: string, providerToken: string, userInfo: any }): Promise; - static authenticate(server: string, provider: string, options: any): Promise; + static login(server: string, credentials: Credentials): Promise | User; static requestPasswordReset(server: string, email: string): Promise; diff --git a/lib/user-methods.js b/lib/user-methods.js index 7ede965b93..23ebb08117 100644 --- a/lib/user-methods.js +++ b/lib/user-methods.js @@ -251,7 +251,7 @@ function refreshAccessToken(user, localRealmPath, realmUrl) { * @param {Function} callback an optional callback with an error and user parameter * @returns {Promise} only returns a promise if the callback parameter was omitted */ -function _authenticate(userConstructor, server, json, callback) { +function _authenticate(userConstructor, server, json) { json.app_id = ''; const url = append_url(server, 'auth'); const options = { @@ -261,7 +261,7 @@ function _authenticate(userConstructor, server, json, callback) { open_timeout: 5000 }; - const promise = performFetch(url, options) + return performFetch(url, options) .then((response) => { const contentType = response.headers.get('Content-Type'); if (contentType.indexOf('application/json') === -1) { @@ -283,17 +283,6 @@ function _authenticate(userConstructor, server, json, callback) { }); } }); - - if (callback) { - promise.then(user => { - callback(null, user); - }) - .catch(err => { - callback(err); - }); - } else { - return promise; - } } function _updateAccount(userConstructor, server, json) { @@ -323,169 +312,86 @@ function _updateAccount(userConstructor, server, json) { } const staticMethods = { - get current() { - const allUsers = this.all; - 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]]; - }, - - adminUser(token, server) { - checkTypes(arguments, ['string', 'string']); - return this._adminUser(server, token); - }, - - register(server, username, password, callback) { - checkTypes(arguments, ['string', 'string', 'string', 'function']); - const json = { - provider: 'password', - user_info: { password: password, register: true }, - data: username - }; - - if (callback) { - const message = "register(..., callback) is now deprecated in favor of register(): Promise. This function argument will be removed in future versions."; - (console.warn || console.log).call(console, message); - } - - return _authenticate(this, server, json, callback); - }, + get current() { + const allUsers = this.all; + const keys = Object.keys(allUsers); + if (keys.length === 0) { + return undefined; + } else if (keys.length > 1) { + throw new Error("Multiple users are logged in"); + } - login(server, username, password, callback) { - checkTypes(arguments, ['string', 'string', 'string', 'function']); - const json = { - provider: 'password', - user_info: { password: password, register: false }, - data: username - }; + return allUsers[keys[0]]; + }, - if (callback) { - const message = "login(..., callback) is now deprecated in favor of login(): Promise. This function argument will be removed in future versions."; - (console.warn || console.log).call(console, message); - } + login(server, credentials) { + checkTypes(arguments, ['string', 'object']); + if (credentials.provider === 'adminToken') { + return this._adminUser(server, credenitals.token); + } - return _authenticate(this, server, json, callback); - }, + return _authenticate(this, server, credentials.toJSON()); + }, - registerWithProvider(server, options, callback) { + deserialize(serialized) { + checkObjectTypes(serialized, { + server: 'string', + identity: 'string', + refreshToken: 'string', + isAdmin: 'boolean', + }); - // Compatibility with previous signature: - // registerWithProvider(server, provider, providerToken, callback) - if (arguments.length === 4) { - checkTypes(arguments, ['string', 'string', 'string', 'function']); - options = { - provider: arguments[1], - providerToken: arguments[2] - }; - callback = arguments[3]; - } else { - checkTypes(arguments, ['string', 'object', 'function']); - } + return this.createUser(serialized.server, serialized.identity, serialized.refreshToken, false, serialized.isAdmin || false); + }, - let json = { - provider: options.provider, - data: options.providerToken, - }; + requestPasswordReset(server, email) { + checkTypes(arguments, ['string', 'string']); + const json = { + provider_id: email, + data: { action: 'reset_password' } + }; - if (options.userInfo) { - json.user_info = options.userInfo; - } + return _updateAccount(this, server, json); + }, - if (callback) { - const message = "registerWithProvider(..., callback) is now deprecated in favor of registerWithProvider(): Promise. This function argument will be removed in future versions."; - (console.warn || console.log).call(console, message); + completePasswordReset(server, reset_token, new_password) { + checkTypes(arguments, ['string', 'string']); + const json = { + data: { + action: 'complete_reset', + token: reset_token, + new_password: new_password } + }; - return _authenticate(this, server, json, callback); - }, - - authenticate(server, provider, options) { - checkTypes(arguments, ['string', 'string', 'object']) - - var json = {} - switch (provider.toLowerCase()) { - case 'jwt': - json.provider = 'jwt' - json.token = options.token; - break - case 'password': - json.provider = 'password' - json.user_info = { password: options.password } - json.data = options.username - break - default: - Object.assign(json, options) - json.provider = provider - } + return _updateAccount(this, server, json); + }, - return _authenticate(this, server, json) - }, + requestEmailConfirmation(server, email) { + checkTypes(arguments, ['string', 'string']); + const json = { + provider_id: email, + data: { action: 'request_email_confirmation' } + }; - deserialize(serialized) { - checkObjectTypes(serialized, { - server: 'string', - identity: 'string', - refreshToken: 'string', - isAdmin: 'boolean', - }); + return _updateAccount(this, server, json); + }, - return this.createUser(serialized.server, serialized.identity, serialized.refreshToken, false, serialized.isAdmin || false); - }, - - requestPasswordReset(server, email) { - checkTypes(arguments, ['string', 'string']); - const json = { - provider_id: email, - data: { action: 'reset_password' } - }; - - return _updateAccount(this, server, json); - }, - - completePasswordReset(server, reset_token, new_password) { - checkTypes(arguments, ['string', 'string']); - const json = { - data: { - action: 'complete_reset', - token: reset_token, - new_password: new_password - } - }; - - return _updateAccount(this, server, json); - }, - - requestEmailConfirmation(server, email) { - checkTypes(arguments, ['string', 'string']); - const json = { - provider_id: email, - data: { action: 'request_email_confirmation' } - }; - - return _updateAccount(this, server, json); - }, - - confirmEmail(server, confirmation_token) { - checkTypes(arguments, ['string', 'string']); - const json = { - data: { - action: 'confirm_email', - token: confirmation_token - } - }; + confirmEmail(server, confirmation_token) { + checkTypes(arguments, ['string', 'string']); + const json = { + data: { + action: 'confirm_email', + token: confirmation_token + } + }; - return _updateAccount(this, server, json); - }, + return _updateAccount(this, server, json); + }, - _refreshAccessToken: refreshAccessToken, + _refreshAccessToken: refreshAccessToken, }; - const instanceMethods = { logout() { this._logout(); @@ -609,10 +515,64 @@ const instanceMethods = { }, }; +const credentialsMethods = { + usernamePassword(username, password, createUser) { + checkTypes(arguments, ['string', 'string', 'boolean']); + return new Credentials('password', username, { register: createUser, password }); + }, + + facebook(token) { + checkTypes(arguments, ['string']); + return new Credentials('facebook', token); + }, + + google(token) { + checkTypes(arguments, ['string']); + return new Credentials('google', token); + }, + + anonymous() { + return new Credentials('anonymous'); + }, + + nickname(value, isAdmin) { + return new Credentials('nickname', value, { is_admin: isAdmin || false }); + }, + + azureAD(token) { + return new Credentials('azuread', token) + }, + + jwt(token) { + return new Credentials('jwt', token); + }, + + adminToken(token) { + return new Credentials('adminToken', token); + }, +} + +class Credentials { + constructor(provider, token, userInfo) { + this.provider = provider; + this.token = token; + this.userInfo = userInfo; + } + + toJSON() { + return { + data: this.token, + provider: this.provider, + user_info: this.userInfo || {}, + }; + } +} + // Append the permission apis Object.assign(instanceMethods, permissionApis); module.exports = { static: staticMethods, - instance: instanceMethods + instance: instanceMethods, + credentials: credentialsMethods, }; diff --git a/tests/js/admin-user-helper.js b/tests/js/admin-user-helper.js index aadce9445f..4c0e2edcbc 100644 --- a/tests/js/admin-user-helper.js +++ b/tests/js/admin-user-helper.js @@ -10,7 +10,8 @@ const adminName = "realm-admin" const password = ''; exports.createAdminUser = function () { - return Realm.Sync.User.login('http://localhost:9080', adminName, password).then((user) => { + const credentials = Realm.Sync.Credentials.usernamePassword(adminName, password); + return Realm.Sync.User.login('http://localhost:9080', credentials).then((user) => { if (!user.isAdmin) { throw new Error(`${adminName} user is not an admin user on this server`); } diff --git a/tests/js/download-api-helper.js b/tests/js/download-api-helper.js index 46076544a8..31e945f0fb 100644 --- a/tests/js/download-api-helper.js +++ b/tests/js/download-api-helper.js @@ -40,15 +40,11 @@ function createObjects(user) { }); } -let registrationError; -Realm.Sync.User.register('http://localhost:9080', username, 'password') - .catch((error) => { - registrationError = JSON.stringify(error); - return Realm.Sync.User.login('http://localhost:9080', username, 'password') - }) +const credentials = Realm.Sync.Credentials.nickname(username); +Realm.Sync.User.login('http://localhost:9080', credentials) .catch((error) => { const loginError = JSON.stringify(error); - console.error(`download-api-helper failed:\n User.register() error:\n${registrationError}\n User.login() error:\n${registrationError}`); + console.error(`download-api-helper failed:\n User login error:\n${loginError}`); process.exit(-2); }) .then((user) => createObjects(user)) diff --git a/tests/js/encryption-tests.js b/tests/js/encryption-tests.js index f8c9f68cba..b4195ab47c 100644 --- a/tests/js/encryption-tests.js +++ b/tests/js/encryption-tests.js @@ -75,7 +75,8 @@ module.exports = { return Promise.resolve(); } - return Realm.Sync.User.login('http://localhost:9080', "realm-admin", '').then(adminUser => { + const credentials = Realm.Sync.Credentials.usernamePassword('realm-admin', ''); + return Realm.Sync.User.login('http://localhost:9080', credentials).then(adminUser => { new Realm({ encryptionKey: new Int8Array(64), sync: { diff --git a/tests/js/nested-list-helper.js b/tests/js/nested-list-helper.js index 7de46e5ee2..b0d2fa6926 100644 --- a/tests/js/nested-list-helper.js +++ b/tests/js/nested-list-helper.js @@ -1,5 +1,5 @@ /* -This script creates new nested objects into a new Realm. +This script creates new nested objects into a new Realm. */ 'use strict'; @@ -54,15 +54,11 @@ function createObjects(user) { }); } -let registrationError; -Realm.Sync.User.register('http://localhost:9080', username, 'password') - .catch((error) => { - registrationError = JSON.stringify(error); - return Realm.Sync.User.login('http://localhost:9080', username, 'password') - }) +const credentials = Realm.Sync.Credentials.nickname(username); +Realm.Sync.User.login('http://localhost:9080', credentials) .catch((error) => { const loginError = JSON.stringify(error); - console.error(`nested-list-helper failed:\n User.register() error:\n${registrationError}\n User.login() error:\n${registrationError}`); + console.error(`nested-list-helper failed:\n User login error:\n${loginError}`); process.exit(-2); }) .then((user) => createObjects(user)) diff --git a/tests/js/object-id-tests.js b/tests/js/object-id-tests.js index faf778a941..8b96f9e6bc 100644 --- a/tests/js/object-id-tests.js +++ b/tests/js/object-id-tests.js @@ -47,8 +47,9 @@ module.exports = { if (!global.enableSyncTests) { return Promise.resolve(); } - - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then(user => { + + const credentials = Realm.Sync.Credentials.anonymous(); + return Realm.Sync.User.login('http://localhost:9080', credentials).then(user => { const config = user.createConfiguration({ sync: { url: 'realm://localhost:9080/~/myrealm' }, schema: [{ name: 'IntegerPrimaryKey', properties: { int: 'int?' }, primaryKey: 'int' }, { name: 'StringPrimaryKey', properties: { string: 'string?' }, primaryKey: 'string' }, diff --git a/tests/js/partial-sync-api-helper.js b/tests/js/partial-sync-api-helper.js index e64a3bbb41..04039fd239 100644 --- a/tests/js/partial-sync-api-helper.js +++ b/tests/js/partial-sync-api-helper.js @@ -57,15 +57,11 @@ function createObjects(user) { }); } -let registrationError; -Realm.Sync.User.register('http://localhost:9080', username, 'password') - .catch((error) => { - registrationError = JSON.stringify(error); - return Realm.Sync.User.login('http://localhost:9080', username, 'password') - }) +const credentials = Realm.Sync.Credentials.nickname(username); +Realm.Sync.User.login('http://localhost:9080', credentials) .catch((error) => { const loginError = JSON.stringify(error); - console.error(`partial-sync-api-helper failed:\n User.register() error:\n${registrationError}\n User.login() error:\n${registrationError}`); + console.error(`partial-sync-api-helper failed:\n User login error:\n${loginError}`); process.exit(-2); }) .then((user) => createObjects(user)) diff --git a/tests/js/permission-tests.js b/tests/js/permission-tests.js index 93d945bd08..8e71c20eef 100644 --- a/tests/js/permission-tests.js +++ b/tests/js/permission-tests.js @@ -31,7 +31,7 @@ function uuid() { function createUsersWithTestRealms(count) { const createUserWithTestRealm = () => { return Realm.Sync.User - .register('http://localhost:9080', uuid(), 'password') + .login('http://localhost:9080', Realm.Sync.Credentials.anonymous()) .then(user => { new Realm({sync: {user, url: 'realm://localhost:9080/~/test', fullSynchronization: true }}).close(); return user; @@ -190,11 +190,11 @@ module.exports = { }; let owner, otherUser return Realm.Sync.User - .register('http://localhost:9080', uuid(), 'password') + .login('http://localhost:9080', Realm.Sync.Credentials.nickname(uuid())) .then(user => { owner = user; new Realm({sync: {user, url: 'realm://localhost:9080/default'}}).close(); - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password') + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.nickname(uuid())) }) .then((user) => { otherUser = user; diff --git a/tests/js/session-tests.js b/tests/js/session-tests.js index 2ccc4ba07c..3fcf3b8df3 100644 --- a/tests/js/session-tests.js +++ b/tests/js/session-tests.js @@ -95,14 +95,11 @@ module.exports = { return; } - const username = uuid(); - const realmName = uuid(); - - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then(user => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then(user => { let config = { - sync: { - user, - url: `realm://localhost:9080/~/${realmName}`, + sync: { + user, + url: `realm://localhost:9080/~/${uuid()}`, fullSynchronization: true, custom_http_headers: { 'X-Foo': 'Bar' @@ -121,7 +118,7 @@ module.exports = { }, testProperties() { - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then(user => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then(user => { return new Promise((resolve, reject) => { const accessTokenRefreshed = this; let successCounter = 0; @@ -170,12 +167,12 @@ module.exports = { const expectedObjectsCount = 3; let user, config; + + const credentials = Realm.Sync.Credentials.nickname(username); return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH) - .then(() => Realm.Sync.User.login('http://localhost:9080', username, 'password')) + .then(() => Realm.Sync.User.login('http://localhost:9080', credentials)) .then(u => { user = u; - const accessTokenRefreshed = this; - let successCounter = 0; config = { sync: { user, url: `realm://localhost:9080/~/${realmName}`, fullSynchronization: true }, @@ -206,13 +203,11 @@ module.exports = { const expectedObjectsCount = 3; let user, config; + const credentials = Realm.Sync.Credentials.nickname(username); return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH) - .then(() => Realm.Sync.User.login('http://localhost:9080', username, 'password')) + .then(() => Realm.Sync.User.login('http://localhost:9080', credentials)) .then(u => { user = u; - const accessTokenRefreshed = this; - let successCounter = 0; - config = { sync: { user, url: `realm://localhost:9080/~/${realmName}`, fullSynchronization: true }, schema: [{ name: 'Dog', properties: { name: 'string' } }], @@ -249,12 +244,10 @@ module.exports = { const realmName = uuid(); const expectedObjectsCount = 3; + const credentials = Realm.Sync.Credentials.nickname(username); return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH) - .then(() => Realm.Sync.User.login('http://localhost:9080', username, 'password')) + .then(() => Realm.Sync.User.login('http://localhost:9080', credentials)) .then(user => { - const accessTokenRefreshed = this; - let successCounter = 0; - let config = { sync: { user, url: `realm://localhost:9080/~/${realmName}`, fullSynchronization: true }, schema: [{ name: 'Dog', properties: { name: 'string' } }], @@ -300,12 +293,10 @@ module.exports = { const realmName = uuid(); const expectedObjectsCount = 3; - return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH) - .then(() => Realm.Sync.User.login('http://localhost:9080', username, 'password')) + const credentials = Realm.Sync.Credentials.nickname(username); + return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH) + .then(() => Realm.Sync.User.login('http://localhost:9080', credentials)) .then(user => { - const accessTokenRefreshed = this; - let successCounter = 0; - let config = { sync: { user, url: `realm://localhost:9080/~/${realmName}`, fullSynchronization: true } }; @@ -400,7 +391,7 @@ module.exports = { }, testErrorHandling() { - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then(user => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then(user => { return new Promise((resolve, _reject) => { const config = user.createConfiguration({ sync: { url: 'realm://localhost:9080/~/myrealm' } }); config.sync.error = (sender, error) => { @@ -430,8 +421,9 @@ module.exports = { const username = uuid(); const realmName = uuid(); + const credentials = Realm.Sync.Credentials.nickname(username); return runOutOfProcess(__dirname + '/nested-list-helper.js', __dirname + '/schemas.js', username, realmName, REALM_MODULE_PATH) - .then(() => Realm.Sync.User.login('http://localhost:9080', username, 'password')) + .then(() => Realm.Sync.User.login('http://localhost:9080', credentials)) .then(user => { let config = { schema: [schemas.ParentObject, schemas.NameObject], @@ -471,7 +463,7 @@ module.exports = { Realm.copyBundledRealmFiles(); } - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password') + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()) .then(user => { const config = { path: realm, @@ -514,7 +506,7 @@ module.exports = { Realm.copyBundledRealmFiles(); } - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then(user => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then(user => { return new Promise((resolve, _reject) => { const config = { path: realm, @@ -555,7 +547,7 @@ module.exports = { Realm.copyBundledRealmFiles(); } - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then(user => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then(user => { return new Promise((resolve, _reject) => { const config = { path: realm, @@ -626,8 +618,9 @@ module.exports = { const username = uuid(); const realmName = uuid(); + const credentials = Realm.Sync.Credentials.nickname(username); return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH) - .then(() => Realm.Sync.User.login('http://localhost:9080', username, 'password')) + .then(() => Realm.Sync.User.login('http://localhost:9080', credentials)) .then(user => { let config = { sync: { @@ -693,8 +686,9 @@ module.exports = { const realmName = uuid(); let progressCalled = false; + const credentials = Realm.Sync.Credentials.nickname(username); return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH) - .then(() => Realm.Sync.User.login('http://localhost:9080', username, 'password')) + .then(() => Realm.Sync.User.login('http://localhost:9080', credentials)) .then(user => { let config = { sync: { @@ -719,8 +713,9 @@ module.exports = { const username = uuid(); const realmName = uuid(); + const credentials = Realm.Sync.Credentials.nickname(username); return runOutOfProcess(__dirname + '/download-api-helper.js', username, realmName, REALM_MODULE_PATH) - .then(() => Realm.Sync.User.login('http://localhost:9080', username, 'password')) + .then(() => Realm.Sync.User.login('http://localhost:9080', credentials)) .then(user => { return new Promise((resolve, reject) => { let config = { @@ -826,9 +821,10 @@ module.exports = { TestCase.assertThrows(() => { let realm = new Realm(config); } ); } + const credentials = Realm.Sync.Credentials.nickname(username); return runOutOfProcess(__dirname + '/partial-sync-api-helper.js', username, REALM_MODULE_PATH) .then(() => { - return Realm.Sync.User.login('http://localhost:9080', username, 'password').then((u) => { + return Realm.Sync.User.login('http://localhost:9080', credentials).then((u) => { user = u; __partialIsAllowed(); @@ -911,7 +907,7 @@ module.exports = { return; } - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then(user => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then(user => { return new Promise((resolve, _reject) => { var realm; const config = user.createConfiguration({ sync: { url: 'realm://localhost:9080/~/myrealm' } }); @@ -944,7 +940,7 @@ module.exports = { return; } - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then((u) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((u) => { return new Promise((resolve, reject) => { let config = { sync: { @@ -953,7 +949,7 @@ module.exports = { fullSynchronization: true, } }; - + Realm.open(config).then(realm => { realm.syncSession.addConnectionNotification((newState, oldState) => { if (oldState === Realm.Sync.ConnectionState.Connected && newState === Realm.Sync.ConnectionState.Disconnected) { @@ -971,7 +967,7 @@ module.exports = { return; } - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then((u) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((u) => { return new Promise((resolve, reject) => { let config = { sync: { @@ -980,7 +976,7 @@ module.exports = { fullSynchronization: true, } }; - + Realm.open(config).then(realm => { let callback1 = () => { reject("Should not be called"); @@ -1005,7 +1001,7 @@ module.exports = { return; } - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then((u) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((u) => { return new Promise((resolve, reject) => { let config = { sync: { @@ -1051,7 +1047,7 @@ module.exports = { return; } - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then((u) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((u) => { return new Promise((resolve, reject) => { let realm = new Realm(u.createConfiguration()); TestCase.assertEqual(5, realm.objects(Realm.Permissions.Class.schema.name).length); diff --git a/tests/js/user-tests.js b/tests/js/user-tests.js index df15f5641f..6e29122aa2 100644 --- a/tests/js/user-tests.js +++ b/tests/js/user-tests.js @@ -68,8 +68,7 @@ function assertIsAuthError(error, code, title) { module.exports = { testLogout() { - const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { assertIsUser(user); assertIsSameUser(user, Realm.Sync.User.current); @@ -84,8 +83,7 @@ module.exports = { }, testRegisterUser() { - const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { // Can we open a realm with the registered user? const realm = new Realm({sync: {user: user, url: 'realm://localhost:9080/~/test'}}); TestCase.assertInstanceOf(realm, Realm); @@ -94,9 +92,10 @@ module.exports = { testRegisterExistingUser() { const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + const credentials = Realm.Sync.Credentials.usernamePassword(username, 'password', true); + return Realm.Sync.User.login('http://localhost:9080', credentials).then((user) => { assertIsUser(user); - return Realm.Sync.User.register('http://localhost:9080', username, 'password') + return Realm.Sync.User.login('http://localhost:9080', credentials) .then((user) => { throw new Error(user); }) .catch((e) => { assertIsAuthError(e, 611, "The provided credentials are invalid or the user does not exist."); @@ -105,43 +104,43 @@ module.exports = { }, testRegisterMissingUsername() { - TestCase.assertThrows(() => Realm.Sync.User.register('http://localhost:9080', undefined, 'password')); + TestCase.assertThrows(() => Realm.Sync.Credentials.usernamePassword(undefined, 'password')); }, testRegisterMissingPassword() { - const username = uuid(); - TestCase.assertThrows(() => Realm.Sync.User.register('http://localhost:9080', username, undefined)); + TestCase.assertThrows(() => Realm.Sync.Credentials.usernamePassword(uuid(), undefined)); }, testRegisterServerOffline() { - const username = uuid(); // Because it waits for answer this takes some time.. - return Realm.Sync.User.register('http://fake_host.local', username, 'password') + return Realm.Sync.User.login('http://fake_host.local', Realm.Sync.Credentials.anonymous()) .catch((e) => {}) .then((user) => { if (user) { throw new Error('should not have been able to register'); }}) }, testLogin() { - const username = uuid(); - // Create user, logout the new user, then login - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { - user.logout(); - return Realm.Sync.User.login('http://localhost:9080', username, 'password'); - }).then((user => { - assertIsUser(user); - // Can we open a realm with the logged-in user? - const config = user.createConfiguration({ sync: { url: 'realm://localhost:9080/~/test' }}); - const realm = new Realm(config); - TestCase.assertInstanceOf(realm, Realm); - realm.close(); - })) + const username = uuid(); + const registerCredentials = Realm.Sync.Credentials.usernamePassword(username, 'password', true); + // Create user, logout the new user, then login + return Realm.Sync.User.login('http://localhost:9080', registerCredentials).then((user) => { + user.logout(); + const loginCredentials = Realm.Sync.Credentials.usernamePassword(username, 'password', false); + return Realm.Sync.User.login('http://localhost:9080', loginCredentials); + }).then((user => { + assertIsUser(user); + // Can we open a realm with the logged-in user? + const config = user.createConfiguration({ sync: { url: 'realm://localhost:9080/~/test' }}); + const realm = new Realm(config); + TestCase.assertInstanceOf(realm, Realm); + realm.close(); + })) }, testAuthenticateWithPassword() { const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.usernamePassword(username, 'password', true)).then((user) => { user.logout(); - return Realm.Sync.User.authenticate('http://localhost:9080', 'password', { username: username, password: 'password' }); + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.usernamePassword(username, 'password')); }).then((user => { assertIsUser(user); const realm = new Realm(user.createConfiguration({ sync: { url: 'realm://localhost:9080/~/test' } })); @@ -160,25 +159,14 @@ module.exports = { }, testLoginNonExistingUser() { - return Realm.Sync.User.login('http://localhost:9080', 'does_not', 'exist') + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.usernamePassword('foo', 'pass', false)) .then((user) => { throw new Error(user); }) .catch((e) => assertIsAuthError(e, 611, "The provided credentials are invalid or the user does not exist.")) }, - testLoginServerOffline() { - const username = uuid(); - - // Because it waits for answer this takes some time.. - return Realm.Sync.User.register('http://fake_host.local', username, 'password') - .then((user) => { throw new Error(user); }) - .catch((e) => assertIsError(e)); - }, - testLoginTowardsMisbehavingServer() { - const username = uuid(); - // Try authenticating towards a server thats clearly not ROS - return Realm.Sync.User.register('https://github.com/realm/realm-js', username, 'user') + return Realm.Sync.User.login('https://github.com/realm/realm-js', Realm.Sync.Credentials.anonymous()) .catch((e) => { assertIsError(e); TestCase.assertEqual( @@ -188,15 +176,9 @@ module.exports = { }); }, - testAuthenticateInvalidProvider() { - return Realm.Sync.User.authenticate('http://localhost:9080', 'FooBar', {}) - .then((user) => { Promise.reject() } ) - .catch((e) => { Promise.resolve() } ) - }, - testAuthenticateJWT() { let token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJhdXN0aW5femhlbmciLCJpc0FkbWluIjp0cnVlLCJpYXQiOjE1MTI2OTI3NDl9.klca-3wYLe5mGdVk7N7dE9YRIlB1el1Dv6BxZNAKMsJ3Ms4vBTweu4-65kVJftiMrYhmSGY6QtTzqQ-xlLH4XzPd3jYIXlPQ45lxO7PW7EkJNs9m83VdcsJmHRHQ3PRP8V_mx0f2Ks4ga3xZ9IycAQB4q5NXLei_HJk8tRRJccZ6qB5nnAoD48Qu8JOEfhO596Mdoi-QCbH51iJZjgXo4gSRZ4KKK8jU0S6twLj_lf9jehENTqHDdtsRHdyCnICcPcz4AjFrNHEvUrsPkGxXSZ2BCGgDcvsSTVgGNV7rWU4IjH4FaDssenumi50R1QcZh8kiO35s9H6MngQsEm-zApRgd0V9_L3A6Ys47_crmKbunYRsATfMNBn2fKm5tS6RXvM2RN2G_Y9AkGgh2boY42CRy7HOcHby2vQ8IoQ-fZfE5xn_YYktNlKeNiCv3_-i86lANFbmB3tcdScrbjsgO6Tfg3u71VmJ_ZW1_vyMi5vCTEysLXfHG-OA85c3o8-25vcfuX5gIpbU-nMLgPagyn5w7Uazd27uhFfwepP9OMc8jz2JTlQICInLCUdESu8aG5d1F_IPUA5NU_ryPmebqUmyaRVDS8cGChxp0gZDNSiIvaggw8N2JCDGvk-s_PSG2pFGq0f4veYyWGBTHD_iX4a0UrhB471QZplRpMwvu7o' - return Realm.Sync.User.authenticate('http://localhost:9080', 'jwt', { token: token }) + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.jwt(token)) .then((user) => { TestCase.assertEqual(user.identity, 'austin_zheng') Promise.resolve() @@ -209,13 +191,13 @@ module.exports = { TestCase.assertArrayLength(Object.keys(all), 0); let user1; - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { const all = Realm.Sync.User.all; TestCase.assertArrayLength(Object.keys(all), 1); assertIsSameUser(all[user.identity], user); user1 = user; - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password'); + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()); }).then((user2) => { let all = Realm.Sync.User.all; TestCase.assertArrayLength(Object.keys(all), 2); @@ -238,11 +220,11 @@ module.exports = { TestCase.assertUndefined(Realm.Sync.User.current); let user1; - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { user1 = user; assertIsSameUser(Realm.Sync.User.current, user1); - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password'); + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()); }).then((user2) => { TestCase.assertThrows(() => Realm.Sync.User.current, 'We expect Realm.Sync.User.current to throw if > 1 user.'); user2.logout(); @@ -255,8 +237,7 @@ module.exports = { }, testGetExistingUser() { - let userid = uuid(); - return Realm.Sync.User.register('http://localhost:9080', userid, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { let identity = user.identity; let user1 = Realm.Sync.User._getExistingUser('http://localhost:9080', identity); assertIsSameUser(user1, user); @@ -267,7 +248,7 @@ module.exports = { }, testManagementRealm() { - return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { let realm = user.openManagementRealm(); TestCase.assertInstanceOf(realm, Realm); @@ -285,7 +266,8 @@ module.exports = { throw new Error("Test requires an admin user"); } - return Realm.Sync.User.login('http://localhost:9080', global.testAdminUserInfo.username, global.testAdminUserInfo.password).then((user) => { + const credentials = Realm.Sync.Credentials.usernamePassword(global.testAdminUserInfo.username, global.testAdminUserInfo.password); + return Realm.Sync.User.login('http://localhost:9080', credentials).then((user) => { TestCase.assertTrue(user.isAdmin, "Test requires an admin user"); return user.retrieveAccount('password', global.testAdminUserInfo.username) @@ -306,7 +288,8 @@ module.exports = { throw new Error("Test requires an admin user"); } - return Realm.Sync.User.login('http://localhost:9080', global.testAdminUserInfo.username, global.testAdminUserInfo.password).then((user) => { + const credentials = Realm.Sync.Credentials.usernamePassword(global.testAdminUserInfo.username, global.testAdminUserInfo.password); + return Realm.Sync.User.login('http://localhost:9080', credentials).then((user) => { TestCase.assertTrue(user.isAdmin, "Test requires an admin user"); let notExistingUsername = uuid(); @@ -320,8 +303,7 @@ module.exports = { }, testCreateConfiguration_defaultConfig() { - const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { let config = user.createConfiguration(); TestCase.assertEqual(config.sync.url, "realm://localhost:9080/default"); TestCase.assertUndefined(config.sync.partial); @@ -330,8 +312,7 @@ module.exports = { }, testCreateConfiguration_useOldConfiguration() { - const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { let config = user.createConfiguration({ sync: { url: 'http://localhost:9080/other_realm', partial: true }}); TestCase.assertEqual(config.sync.url, 'http://localhost:9080/other_realm'); TestCase.assertUndefined(config.sync.fullSynchronization); @@ -340,8 +321,7 @@ module.exports = { }, testCreateConfiguration_settingPartialAndFullSynchronizationThrows() { - const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { TestCase.assertThrowsContaining(() => { let config = { sync: { @@ -356,8 +336,7 @@ module.exports = { }, testOpen_partialAndFullSynchronizationSetThrows() { - const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { TestCase.assertThrowsContaining(() => { new Realm({ sync: { @@ -372,8 +351,7 @@ module.exports = { }, testSerialize() { - const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password').then((user) => { + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()).then((user) => { const serialized = user.serialize(); TestCase.assertFalse(serialized.isAdmin); TestCase.assertEqual(serialized.identity, user.identity); @@ -383,8 +361,7 @@ module.exports = { }, testDeserialize() { - const username = uuid(); - return Realm.Sync.User.register('http://localhost:9080', username, 'password') + return Realm.Sync.User.login('http://localhost:9080', Realm.Sync.Credentials.anonymous()) .then((user) => { const userConfig = user.createConfiguration({ schema: [{ name: 'Dog', properties: { name: 'string' } }], diff --git a/tests/package-lock.json b/tests/package-lock.json new file mode 100644 index 0000000000..eed54dd158 --- /dev/null +++ b/tests/package-lock.json @@ -0,0 +1,359 @@ +{ + "name": "realm-tests-jasmine", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bindings": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, + "es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "event-stream": { + "version": "3.3.4", + "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "requires": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "jasmine": { + "version": "2.99.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.99.0.tgz", + "integrity": "sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=", + "requires": { + "exit": "^0.1.2", + "glob": "^7.0.6", + "jasmine-core": "~2.99.0" + } + }, + "jasmine-console-reporter": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/jasmine-console-reporter/-/jasmine-console-reporter-1.2.8.tgz", + "integrity": "sha1-2JPJwMElcn7Xd3Cc9Hh2gNBRU5Y=", + "requires": { + "chalk": "^2.1.0" + } + }, + "jasmine-core": { + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", + "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=" + }, + "jasmine-reporters": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/jasmine-reporters/-/jasmine-reporters-2.3.2.tgz", + "integrity": "sha512-u/7AT9SkuZsUfFBLLzbErohTGNsEUCKaQbsVYnLFW1gEuL2DzmBL4n8v90uZsqIqlWvWUgian8J6yOt5Fyk/+A==", + "requires": { + "mkdirp": "^0.5.1", + "xmldom": "^0.1.22" + } + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.0.tgz", + "integrity": "sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==" + }, + "needle": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-1.6.0.tgz", + "integrity": "sha1-9SpYWJchIWGOAC+OY4TK2sItYk8=", + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "requires": { + "through": "~2.3" + } + }, + "ps-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.0.1.tgz", + "integrity": "sha1-xkBjtM6Ncvf4dJdfPsxfNZesjks=", + "requires": { + "event-stream": "~3.3.0" + } + }, + "querystringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", + "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "segfault-handler": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/segfault-handler/-/segfault-handler-1.0.1.tgz", + "integrity": "sha512-3koBV3F0IPxTYacnoL7WoFlaMndXsXj62tiVbbW9Kzp3K+F9Y6GWW5XmKSv7j+7nf2M+qjNzc4W1iZoa8vocjw==", + "requires": { + "bindings": "^1.2.1", + "nan": "^2.0.9" + } + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "requires": { + "through": "2" + } + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "requires": { + "duplexer": "~0.1.1" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "terminate": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/terminate/-/terminate-1.0.8.tgz", + "integrity": "sha1-FwPVBhS2/7oX0ZBphXH49isZfAw=", + "requires": { + "ps-tree": "1.0.1" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "typescript": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", + "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==" + }, + "url-parse": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz", + "integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==", + "requires": { + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xmldom": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", + "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" + } + } +} From f9f03e42fbb2922e6f24abbc93888546ba5fc86e Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Mon, 3 Sep 2018 13:19:05 +0200 Subject: [PATCH 2/9] Fix docs --- docs/sync.js | 46 +++++++++++++++++++++++---------------------- lib/index.d.ts | 2 +- lib/user-methods.js | 24 +++++++++++++---------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/docs/sync.js b/docs/sync.js index c642f81645..85ccecef17 100644 --- a/docs/sync.js +++ b/docs/sync.js @@ -300,28 +300,29 @@ class Credentials { * `true` is provided and the user exists, or `false` is provided and the user doesn't exist, * an error will be thrown. If not specified, if the user doesn't exist, they will be created, * otherwise, they'll be logged in if the password matches. - * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ static usernamePassword(username, password, createUser) {}; /** * Creates credentials based on a Facebook login. * @param {string} token A Facebook authentication token, obtained by logging into Facebook.. - * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ - static facebook(token); + static facebook(token) {}; /** * Creates credentials based on a Google login. * @param {string} token A Google authentication token, obtained by logging into Google.. - * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. + */ static google(token) {}; /** * Creates credentials for an anonymous user. These can only be used once - using them a second * time will result in a different user being logged in. If you need to get a user that has already logged - * in with the Anonymous credentials, use @see {User.current} or @see {User.all} - * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + * in with the Anonymous credentials, use {@linkcode Realm.Sync.User.current|User.current} or {@linkcode Realm.Sync.User.all|User.all} + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ static anonymous() {}; @@ -330,28 +331,28 @@ class Credentials { * with the same nickname, they'll get the same underlying sync user. * @param {string} value The nickname of the user. * @param {boolean} isAdmin An optional parameter controlling whether the user is admin. - * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ static nickname(value, isAdmin) {}; /** * Creates credentials based on an Active Directory login. * @param {string} token An access token, obtained by logging into Azure Active Directory. - * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ static azureAD(token) {}; /** * Creates credentials based on a JWT login. * @param {string} token A Json Web Token, that will be validated against the server's configured rules. - * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ static jwt(token) {}; /** * Creates credentials based on an admin token. Using this credential will not contact the Realm Object Server. * @param {string} token The admin token. - * @return {Credentials} An instance of `Credentials` that can be used in @see {User.login}. + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ static adminToken(token) {}; @@ -359,32 +360,33 @@ class Credentials { * Gets the identity provider for the credentials. * @returns {string} The identity provider, such as Google, Facebook, etc. */ - get provider(); + get identityProvider() {}; /** * Gets the access token. * @returns {string} */ - get token(); + get token() {}; /** * Gets additional user information associated with the credentials. * @returns {object} A dictionary, containing the additional information. */ - get userInfo(); - + get userInfo() {}; } /** - * Class for logging in and managing Sync users. + * Class for managing Sync users. * @memberof Realm.Sync */ class User { /** * Logs the user in to the Realm Object Server. * @param {string} server The url of the server that the user is authenticated against. - * @param {Credentials} credentials The credentials to use for authentication. Obtain them by calling one of the - * @see {Credentials} static methods. + * @param {Credentials} credentials The credentials to use for authentication. Obtain them by calling one of + * the {@linkcode Realm.Sync.Credentials|Credentials} static methods. + * @return {Promise | User} A {@linkcode Realm.Sync.User|User} object if the credentials are + * {@linkcode Realm.Sync.Credentials.adminToken|adminToken}, {@link Realm.Sync.User|`Promise`} otherwise. */ static login(server, credentials) {} @@ -408,11 +410,11 @@ class User { * open the app, extract the token, and navigate to a view that allows to change the password within the app. * * @param {string} server - authentication server - * @param {string} reset_token - The token that was sent to the user's email address. - * @param {string} new_password - The user's new password. + * @param {string} resetToken - The token that was sent to the user's email address. + * @param {string} newPassword - The user's new password. * @return {Promise} A promise which is resolved when the request has been sent. */ - static completePasswordReset(server, reset_token, new_password) {} + static completePasswordReset(server, resetToken, newPassword) {} /** * Request an email confirmation email to be sent to a user's email. @@ -432,10 +434,10 @@ class User { * open the app, extract the token, and navigate to a view that allows to confirm the email within the app. * * @param {string} server - authentication server - * @param {string} confirmation_token - The token that was sent to the user's email address. + * @param {string} confirmationToken - The token that was sent to the user's email address. * @return {Promise} A promise which is resolved when the request has been sent. */ - static confirmEmail(server, confirmation_token) {} + static confirmEmail(server, confirmationToken) {} /** * Create an admin user for the given authentication server with an existing token diff --git a/lib/index.d.ts b/lib/index.d.ts index 52e17bddf2..f7d11c6ccb 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -300,7 +300,7 @@ declare namespace Realm.Sync { static jwt(token: string): Credentials; static adminToken(token: string): Credentials; - readonly provider: string; + readonly identityProvider: string; readonly token: string; readonly userInfo: { [key: string]: any }; } diff --git a/lib/user-methods.js b/lib/user-methods.js index 23ebb08117..d6ad72991f 100644 --- a/lib/user-methods.js +++ b/lib/user-methods.js @@ -326,11 +326,11 @@ const staticMethods = { login(server, credentials) { checkTypes(arguments, ['string', 'object']); - if (credentials.provider === 'adminToken') { + if (credentials.identityProvider === 'adminToken') { return this._adminUser(server, credenitals.token); } - return _authenticate(this, server, credentials.toJSON()); + return _authenticate(this, server, credentials); }, deserialize(serialized) { @@ -354,13 +354,13 @@ const staticMethods = { return _updateAccount(this, server, json); }, - completePasswordReset(server, reset_token, new_password) { + completePasswordReset(server, resetToken, newPassword) { checkTypes(arguments, ['string', 'string']); const json = { data: { action: 'complete_reset', - token: reset_token, - new_password: new_password + token: resetToken, + new_password: newPassword } }; @@ -377,12 +377,12 @@ const staticMethods = { return _updateAccount(this, server, json); }, - confirmEmail(server, confirmation_token) { + confirmEmail(server, confirmationToken) { checkTypes(arguments, ['string', 'string']); const json = { data: { action: 'confirm_email', - token: confirmation_token + token: confirmationToken } }; @@ -536,25 +536,29 @@ const credentialsMethods = { }, nickname(value, isAdmin) { + checkTypes(arguments, ['string', 'boolean']); return new Credentials('nickname', value, { is_admin: isAdmin || false }); }, azureAD(token) { + checkTypes(arguments, ['string']); return new Credentials('azuread', token) }, jwt(token) { + checkTypes(arguments, ['string']); return new Credentials('jwt', token); }, adminToken(token) { + checkTypes(arguments, ['string']); return new Credentials('adminToken', token); }, } class Credentials { - constructor(provider, token, userInfo) { - this.provider = provider; + constructor(identityProvider, token, userInfo) { + this.identityProvider = identityProvider; this.token = token; this.userInfo = userInfo; } @@ -562,7 +566,7 @@ class Credentials { toJSON() { return { data: this.token, - provider: this.provider, + provider: this.identityProvider, user_info: this.userInfo || {}, }; } From 5ae80319473df96c68571ed7f2e31a376ca00d2c Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Mon, 3 Sep 2018 13:30:46 +0200 Subject: [PATCH 3/9] Allow to override the jwt provider name --- docs/sync.js | 10 ++++++---- lib/index.d.ts | 6 +++--- lib/user-methods.js | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/sync.js b/docs/sync.js index 85ccecef17..2db64ae278 100644 --- a/docs/sync.js +++ b/docs/sync.js @@ -296,7 +296,7 @@ class Credentials { * Creates credentials based on a login with a username and a password. * @param {string} username The username of the user. * @param {string} password The user's password. - * @param {boolean} createUser optional - `true` if the user should be created, `false` otherwise. If + * @param {boolean} [createUser] optional - `true` if the user should be created, `false` otherwise. If * `true` is provided and the user exists, or `false` is provided and the user doesn't exist, * an error will be thrown. If not specified, if the user doesn't exist, they will be created, * otherwise, they'll be logged in if the password matches. @@ -330,7 +330,7 @@ class Credentials { * Creates credentials based on a login with a nickname. If multiple users try to login * with the same nickname, they'll get the same underlying sync user. * @param {string} value The nickname of the user. - * @param {boolean} isAdmin An optional parameter controlling whether the user is admin. + * @param {boolean} [isAdmin] An optional parameter controlling whether the user is admin. Default is `false`. * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ static nickname(value, isAdmin) {}; @@ -345,9 +345,11 @@ class Credentials { /** * Creates credentials based on a JWT login. * @param {string} token A Json Web Token, that will be validated against the server's configured rules. + * @param {string} [providerName] The name of the provider as configured in the Realm Object. If not specified, the default + * name - `jwt` - will be used. * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. */ - static jwt(token) {}; + static jwt(token, providerName) {}; /** * Creates credentials based on an admin token. Using this credential will not contact the Realm Object Server. @@ -915,7 +917,7 @@ class Adapter { * Open the Realm used by the Adapter for the given path. This is useful for writing two way * adapters as transactions written to this realm will be ignored when calling `current` and `advance` * @param {string} path - the path for the Realm to open - * @param {Realm~ObjectSchema[]} [optional] schema - schema to apply when opening the Realm + * @param {Realm~ObjectSchema[]} [schema] - optional schema to apply when opening the Realm * @returns {Realm} */ realmAtPath(path, schema) {} diff --git a/lib/index.d.ts b/lib/index.d.ts index f7d11c6ccb..2707636863 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -297,7 +297,7 @@ declare namespace Realm.Sync { static anonymous(): Credentials; static nickname(value: string, isAdmin?: boolean): Credentials; static azureAD(token: string): Credentials; - static jwt(token: string): Credentials; + static jwt(token: string, providerName?: string): Credentials; static adminToken(token: string): Credentials; readonly identityProvider: string; @@ -321,11 +321,11 @@ declare namespace Realm.Sync { static requestPasswordReset(server: string, email: string): Promise; - static completePasswordReset(server:string, reset_token:string, new_password:string): Promise; + static completePasswordReset(server:string, resetToken:string, newPassword:string): Promise; static requestEmailConfirmation(server:string, email:string): Promise; - static confirmEmail(server:string, confirmation_token:string): Promise; + static confirmEmail(server:string, confirmationToken:string): Promise; static deserialize(serialized: SerializedUser): Realm.Sync.User; diff --git a/lib/user-methods.js b/lib/user-methods.js index d6ad72991f..24625cb2f4 100644 --- a/lib/user-methods.js +++ b/lib/user-methods.js @@ -545,9 +545,9 @@ const credentialsMethods = { return new Credentials('azuread', token) }, - jwt(token) { - checkTypes(arguments, ['string']); - return new Credentials('jwt', token); + jwt(token, providerName) { + checkTypes(arguments, ['string', 'string']); + return new Credentials(providerName || 'jwt', token); }, adminToken(token) { From 7fdd5c7073a61e83afe3ed855a50861016e15ad9 Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Mon, 3 Sep 2018 14:48:39 +0200 Subject: [PATCH 4/9] Add custom provider and changelog --- CHANGELOG.md | 18 +++++++++++++++++- docs/sync.js | 25 ++++++++++++++----------- lib/index.d.ts | 1 + lib/user-methods.js | 5 +++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eb7f71788..d667da16d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,23 @@ X.Y.Z Release notes * Realm Object Server: 3.0.0 or later ### Breaking changes -* None. +* The authentication API have been completely revamped. + * The following methods have been removed: + * `Realm.Sync.User.login` + * `Realm.Sync.User.register` + * `Realm.Sync.User.authenticate` + * `Realm.Sync.User.registerWithProvider` + * `Realm.Sync.User.adminUser` + * A new `Realm.Sync.User.login` method has been added that accepts the server url and a credentials object. + * A new class - `Realm.Sync.Credentials` has been added that contains factory methods to create credentials + with all supported providers. + * Here are some examples on how to transform your old code to use the new API: + + | Old | New | + | - | - | + |
const user = await Realm.Sync.User.login(serverUrl, 'username', 'password');
|
const credentials = Realm.Sync.Credentials.usernamePassword('username', 'password');
const user = await Realm.Sync.User.login(serverUrl, credentials);
| + |
const jwtToken = 'acc3ssT0ken...';
const user = await Realm.Sync.User.registerWithProvider(serverUrl, 'jwt', jwtToken);
|
const jwtToken = 'acc3ssT0ken...';
const credentials = Realm.Sync.Credentials.jwt(jwtToken);
const user = await Realm.Sync.User.login(serverUrl, credentials);
| + |
const customToken = 'acc3ssT0ken...';
const userInfo = { someValue: true };
const user = await Realm.Sync.User.registerWithProvider(serverUrl, 'custom/fooauth', customToken, userInfo);
|
const customToken = 'acc3ssT0ken...';
const userInfo = { someValue: true };
const credentials = Realm.Sync.Credentials.custom('custom/fooauth', customToken, userInfo);
const user = await Realm.Sync.User.login(serverUrl, credentials);
| ### Enhancements * Exposed `User.serialize` to create a persistable representation of a user instance, as well as diff --git a/docs/sync.js b/docs/sync.js index 2db64ae278..ff5a451a7e 100644 --- a/docs/sync.js +++ b/docs/sync.js @@ -99,7 +99,7 @@ class Sync { * Add a sync listener to listen to changes across multiple Realms. * * @param {string} serverUrl - The sync server to listen to. - * @param {SyncUser} adminUser - An admin user obtained by calling `new Realm.Sync.User.adminUser`. + * @param {SyncUser} adminUser - an admin user obtained by calling {@linkcode Realm.Sync.User.login|User.login} with admin credentials. * @param {string} filterRegex - A regular expression used to determine which changed Realms should trigger events. Use `.*` to match all Realms. * @param {string} name - The name of the event. * @param {function(changeEvent)} changeCallback - The callback to invoke with the events. @@ -129,7 +129,7 @@ class Sync { * Add a sync listener to listen to changes across multiple Realms. * * @param {string} serverUrl - The sync server to listen to. - * @param {SyncUser} adminUser - An admin user obtained by calling `new Realm.Sync.User.adminUser`. + * @param {SyncUser} adminUser - an admin user obtained by calling {@linkcode Realm.Sync.User.login|User.login} with admin credentials. * @param {string} filterRegex - A regular expression used to determine which changed Realms should trigger events. Use `.*` to match all Realms. * @param {Realm.Worker} worker - Worker to deliver events to. * @@ -358,6 +358,17 @@ class Credentials { */ static adminToken(token) {}; + /** + * Creates credentials with a custom provider and user identifier. + * @param {string} providerName Provider used to verify the credentials. + * @param {string} token A string identifying the user. Usually an identity token or a username. + * @param {userInfo} token Data describing the user further or null if the user does not have any extra data. + * The data will be serialized to JSON, so all values must be mappable to a valid JSON data type. + * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. + */ + static custom(providerName, token, userInfo) {}; + + /** * Gets the identity provider for the credentials. * @returns {string} The identity provider, such as Google, Facebook, etc. @@ -441,14 +452,6 @@ class User { */ static confirmEmail(server, confirmationToken) {} - /** - * Create an admin user for the given authentication server with an existing token - * @param {string} adminToken - existing admin token - * @param {string} server - authentication server - * @return {User} - admin user populated with the given token and server - */ - static adminUser(adminToken, server) {} - /** * Creates a new sync user instance from the serialized representation. * @param {object} serialized - the serialized version of the user, obtained by calling {@link User#serialize}. @@ -837,7 +840,7 @@ class Adapter { * Create a new Adapter to monitor and process changes made across multiple Realms * @param {string} localPath - the local path where realm files are stored * @param {string} serverUrl - the sync server to listen to - * @param {SyncUser} adminUser - an admin user obtained by calling `new Realm.Sync.User.adminUser` + * @param {SyncUser} adminUser - an admin user obtained by calling {@linkcode Realm.Sync.User.login|User.login} with admin credentials. * @param {string} regex - a regular expression used to determine which changed Realms should be monitored - * use `.*` to match all all Realms * @param {function(realmPath)} changeCallback - called when a new transaction is available diff --git a/lib/index.d.ts b/lib/index.d.ts index 2707636863..b135635298 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -299,6 +299,7 @@ declare namespace Realm.Sync { static azureAD(token: string): Credentials; static jwt(token: string, providerName?: string): Credentials; static adminToken(token: string): Credentials; + static custom(providerName: string, token: string, userInfo: {[key: string]: any}): Credentials; readonly identityProvider: string; readonly token: string; diff --git a/lib/user-methods.js b/lib/user-methods.js index 24625cb2f4..ffa4a1d111 100644 --- a/lib/user-methods.js +++ b/lib/user-methods.js @@ -554,6 +554,11 @@ const credentialsMethods = { checkTypes(arguments, ['string']); return new Credentials('adminToken', token); }, + + custom(providerName, token, userInfo) { + checkTypes(arguments, ['string', 'string', 'object']); + return new Credentials(providerName, token, userInfo); + } } class Credentials { From 226299b822e1cb6222c9b7e84f78394f56c5998a Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Mon, 3 Sep 2018 14:56:17 +0200 Subject: [PATCH 5/9] Update CHANGELOG.md --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d667da16d9..4d9006a20a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,9 +21,9 @@ X.Y.Z Release notes | Old | New | | - | - | - |
const user = await Realm.Sync.User.login(serverUrl, 'username', 'password');
|
const credentials = Realm.Sync.Credentials.usernamePassword('username', 'password');
const user = await Realm.Sync.User.login(serverUrl, credentials);
| - |
const jwtToken = 'acc3ssT0ken...';
const user = await Realm.Sync.User.registerWithProvider(serverUrl, 'jwt', jwtToken);
|
const jwtToken = 'acc3ssT0ken...';
const credentials = Realm.Sync.Credentials.jwt(jwtToken);
const user = await Realm.Sync.User.login(serverUrl, credentials);
| - |
const customToken = 'acc3ssT0ken...';
const userInfo = { someValue: true };
const user = await Realm.Sync.User.registerWithProvider(serverUrl, 'custom/fooauth', customToken, userInfo);
|
const customToken = 'acc3ssT0ken...';
const userInfo = { someValue: true };
const credentials = Realm.Sync.Credentials.custom('custom/fooauth', customToken, userInfo);
const user = await Realm.Sync.User.login(serverUrl, credentials);
| + | `const user = await Realm.Sync.User.login(serverUrl, 'username', 'password');` | `const credentials = Realm.Sync.Credentials.usernamePassword('username', 'password');`
`const user = await Realm.Sync.User.login(serverUrl, credentials);` | + | `const jwtToken = 'acc3ssT0ken...';`
`const user = await Realm.Sync.User.registerWithProvider(serverUrl, 'jwt', jwtToken);` | `const jwtToken = 'acc3ssT0ken...';`
`const credentials = Realm.Sync.Credentials.jwt(jwtToken);`
`const user = await Realm.Sync.User.login(serverUrl, credentials);` | + | `const customToken = 'acc3ssT0ken...';`
`const userInfo = { someValue: true };`
`const user = await Realm.Sync.User.registerWithProvider(serverUrl, 'custom/fooauth', customToken, userInfo);` | `const customToken = 'acc3ssT0ken...';`
`const userInfo = { someValue: true };`
`const credentials = Realm.Sync.Credentials.custom('custom/fooauth', customToken, userInfo);`
`const user = await Realm.Sync.User.login(serverUrl, credentials);` | ### Enhancements * Exposed `User.serialize` to create a persistable representation of a user instance, as well as From 3dedd4ae40db417d438e6f8f6cba85f4aad8703a Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Wed, 5 Sep 2018 15:02:18 +0200 Subject: [PATCH 6/9] Bring back legacy methods --- docs/sync.js | 21 +++++++ lib/index.d.ts | 13 ++++ lib/user-methods.js | 142 ++++++++++++++++++++++++++++++-------------- 3 files changed, 130 insertions(+), 46 deletions(-) diff --git a/docs/sync.js b/docs/sync.js index ff5a451a7e..356198586a 100644 --- a/docs/sync.js +++ b/docs/sync.js @@ -603,6 +603,27 @@ class User { * {@link Realm#Sync#User#offerPermissions offerPermissions}. */ invalidatePermissionOffer(permissionOfferOrToken) { } + + // Deprecated + /** + * @deprecated, to be removed in future versions. Use User.login(server, Credentials.usernamePassword) instead. + */ + static register(server, username, password, callback) {} + + /** + * @deprecated, to be removed in future versions. Use User.login(server, Credentials.adminToken) instead. + */ + static adminUser(adminToken, server) {} + + /** + * @deprecated, to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead. + */ + static registerWithProvider(server, options, callback) {} + + /** + * @deprecated, to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead. + */ + static authenticate(server, provider, options) {} } /** diff --git a/lib/index.d.ts b/lib/index.d.ts index b135635298..054be8acf6 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -341,6 +341,19 @@ declare namespace Realm.Sync { offerPermissions(realmUrl: string, accessLevel: AccessLevel, expiresAt?: Date): Promise; acceptPermissionOffer(token: string): Promise invalidatePermissionOffer(permissionOfferOrToken: PermissionOffer | string): Promise; + + // Deprecated + + /** @deprecated, to be removed in future versions */ + static adminUser(adminToken: string, server?: string): User; + /** @deprecated, to be removed in future versions */ + static login(server: string, username: string, password: string): Promise; + /** @deprecated, to be removed in future versions */ + static register(server: string, username: string, password: string): Promise; + /** @deprecated, to be removed in future versions */ + static registerWithProvider(server: string, options: { provider: string, providerToken: string, userInfo: any }): Promise; + /** @deprecated, to be removed in future versions */ + static authenticate(server: string, provider: string, options: any): Promise; } interface _PermissionConditionUserId { diff --git a/lib/user-methods.js b/lib/user-methods.js index ffa4a1d111..90f1f8f3f0 100644 --- a/lib/user-methods.js +++ b/lib/user-methods.js @@ -311,6 +311,52 @@ function _updateAccount(userConstructor, server, json) { }); } +const credentialsMethods = { + usernamePassword(username, password, createUser) { + checkTypes(arguments, ['string', 'string', 'boolean']); + return new Credentials('password', username, { register: createUser, password }); + }, + + facebook(token) { + checkTypes(arguments, ['string']); + return new Credentials('facebook', token); + }, + + google(token) { + checkTypes(arguments, ['string']); + return new Credentials('google', token); + }, + + anonymous() { + return new Credentials('anonymous'); + }, + + nickname(value, isAdmin) { + checkTypes(arguments, ['string', 'boolean']); + return new Credentials('nickname', value, { is_admin: isAdmin || false }); + }, + + azureAD(token) { + checkTypes(arguments, ['string']); + return new Credentials('azuread', token) + }, + + jwt(token, providerName) { + checkTypes(arguments, ['string', 'string']); + return new Credentials(providerName || 'jwt', token); + }, + + adminToken(token) { + checkTypes(arguments, ['string']); + return new Credentials('adminToken', token); + }, + + custom(providerName, token, userInfo) { + checkTypes(arguments, ['string', 'string', 'object']); + return new Credentials(providerName, token, userInfo); + } +} + const staticMethods = { get current() { const allUsers = this.all; @@ -325,6 +371,14 @@ const staticMethods = { }, login(server, credentials) { + if (arguments.length === 3) { + // Deprecated legacy signature. + checkTypes(arguments, ['string', 'string', 'string']); + console.warn("User.login is deprecated. Please use User.login(server, Credentials.usernamePassword(...)) instead."); + const newCredentials = credentialsMethods.usernamePassword(arguments[1], arguments[2], /* createUser */ false); + return this.login(server, newCredentials); + } + checkTypes(arguments, ['string', 'object']); if (credentials.identityProvider === 'adminToken') { return this._adminUser(server, credenitals.token); @@ -390,6 +444,48 @@ const staticMethods = { }, _refreshAccessToken: refreshAccessToken, + + // Deprecated... + adminUser(token, server) { + checkTypes(arguments, ['string', 'string']); + console.warn("User.adminUser is deprecated. Please use User.login(server, Credentials.adminToken(token)) instead."); + const credentials = credentialsMethods.adminToken(token); + return this.login(server, credentials); + }, + + register(server, username, password) { + checkTypes(arguments, ['string', 'string', 'string']); + console.warn("User.register is deprecated. Please use User.login(server, Credentials.usernamePassword(...)) instead."); + const credentials = credentialsMethods.usernamePassword(username, password, /* createUser */ true); + return this.login(server, credentials); + }, + + registerWithProvider(server, options) { + checkTypes(arguments, ['string', 'object']); + console.warn("User.registerWithProvider is deprecated. Please use User.login(server, Credentials.SOME-PROVIDER(...)) instead."); + const credentials = credentialsMethods.custom(options.provider, options.providerToken, options.userInfo); + return this.login(server, credentials); + }, + + authenticate(server, provider, options) { + checkTypes(arguments, ['string', 'string', 'object']) + console.warn("User.authenticate is deprecated. Please use User.login(server, Credentials.SOME-PROVIDER(...)) instead."); + + let credentials; + switch (provider.toLowerCase()) { + case 'jwt': + credentials = credentialsMethods.jwt(options.token, 'jwt'); + break + case 'password': + credentials = credentialsMethods.usernamePassword(options.username, options.password); + break + default: + credentials = credentialsMethods.custom(provider, options.data, options.user_info || options.userInfo); + break; + } + + return this.login(server, credentials); + }, }; const instanceMethods = { @@ -515,52 +611,6 @@ const instanceMethods = { }, }; -const credentialsMethods = { - usernamePassword(username, password, createUser) { - checkTypes(arguments, ['string', 'string', 'boolean']); - return new Credentials('password', username, { register: createUser, password }); - }, - - facebook(token) { - checkTypes(arguments, ['string']); - return new Credentials('facebook', token); - }, - - google(token) { - checkTypes(arguments, ['string']); - return new Credentials('google', token); - }, - - anonymous() { - return new Credentials('anonymous'); - }, - - nickname(value, isAdmin) { - checkTypes(arguments, ['string', 'boolean']); - return new Credentials('nickname', value, { is_admin: isAdmin || false }); - }, - - azureAD(token) { - checkTypes(arguments, ['string']); - return new Credentials('azuread', token) - }, - - jwt(token, providerName) { - checkTypes(arguments, ['string', 'string']); - return new Credentials(providerName || 'jwt', token); - }, - - adminToken(token) { - checkTypes(arguments, ['string']); - return new Credentials('adminToken', token); - }, - - custom(providerName, token, userInfo) { - checkTypes(arguments, ['string', 'string', 'object']); - return new Credentials(providerName, token, userInfo); - } -} - class Credentials { constructor(identityProvider, token, userInfo) { this.identityProvider = identityProvider; From a6358401db946cc84eb7a0b4bd386a819da216e2 Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Wed, 5 Sep 2018 15:04:32 +0200 Subject: [PATCH 7/9] Remove the callback argument from docs --- docs/sync.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sync.js b/docs/sync.js index 356198586a..42ca744370 100644 --- a/docs/sync.js +++ b/docs/sync.js @@ -608,7 +608,7 @@ class User { /** * @deprecated, to be removed in future versions. Use User.login(server, Credentials.usernamePassword) instead. */ - static register(server, username, password, callback) {} + static register(server, username, password) {} /** * @deprecated, to be removed in future versions. Use User.login(server, Credentials.adminToken) instead. @@ -618,7 +618,7 @@ class User { /** * @deprecated, to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead. */ - static registerWithProvider(server, options, callback) {} + static registerWithProvider(server, options) {} /** * @deprecated, to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead. From 64c32f779c9191b67df70e9f963931b1acec80c6 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Thu, 6 Sep 2018 21:43:53 +0200 Subject: [PATCH 8/9] removing command after JSDoc tag --- docs/sync.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sync.js b/docs/sync.js index 42ca744370..1feae22037 100644 --- a/docs/sync.js +++ b/docs/sync.js @@ -606,22 +606,22 @@ class User { // Deprecated /** - * @deprecated, to be removed in future versions. Use User.login(server, Credentials.usernamePassword) instead. + * @deprecated to be removed in future versions. Use User.login(server, Credentials.usernamePassword) instead. */ static register(server, username, password) {} /** - * @deprecated, to be removed in future versions. Use User.login(server, Credentials.adminToken) instead. + * @deprecated to be removed in future versions. Use User.login(server, Credentials.adminToken) instead. */ static adminUser(adminToken, server) {} /** - * @deprecated, to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead. + * @deprecated to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead. */ static registerWithProvider(server, options) {} /** - * @deprecated, to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead. + * @deprecated to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead. */ static authenticate(server, provider, options) {} } From 55a36466dfd08540515284e9139f932a353fd95a Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Wed, 12 Sep 2018 12:25:37 +0200 Subject: [PATCH 9/9] Update some documentation --- CHANGELOG.md | 4 ++-- docs/sync.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d9006a20a..b7fd221e75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,8 @@ X.Y.Z Release notes * Realm Object Server: 3.0.0 or later ### Breaking changes -* The authentication API have been completely revamped. - * The following methods have been removed: +* The authentication API has been completely revamped. + * The following methods have been deprecated and will be removed at a next major version: * `Realm.Sync.User.login` * `Realm.Sync.User.register` * `Realm.Sync.User.authenticate` diff --git a/docs/sync.js b/docs/sync.js index 1feae22037..124c027a2e 100644 --- a/docs/sync.js +++ b/docs/sync.js @@ -344,7 +344,7 @@ class Credentials { /** * Creates credentials based on a JWT login. - * @param {string} token A Json Web Token, that will be validated against the server's configured rules. + * @param {string} token A JSON Web Token, that will be validated against the server's configured rules. * @param {string} [providerName] The name of the provider as configured in the Realm Object. If not specified, the default * name - `jwt` - will be used. * @return {Credentials} An instance of `Credentials` that can be used in {@linkcode Realm.Sync.User.login|User.login}. @@ -537,7 +537,7 @@ class User { * Get account information for a user. (requires administrator privilidges) * @param {string} provider - the provider to query for user account information (ex. 'password') * @param {string} username - the target username which account information should be retrieved - * @returns {Promise} - a promise that will be resolved with the retrieved account information as json object + * @returns {Promise} - a promise that will be resolved with the retrieved account information as JSON object * @example * { * "provider_id": "user@email.co",