diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7becaac65f..9a320e4628 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,23 @@ X.Y.Z Release notes
* Realm Object Server: 3.0.0 or later
### Breaking changes
-* None.
+* 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`
+ * `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 1123f1518d..1e4fb69a8c 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.
*
@@ -288,58 +288,120 @@ 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 {@linkcode Realm.Sync.User.login|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 {@linkcode Realm.Sync.User.login|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 {@linkcode Realm.Sync.User.login|User.login}.
*/
- static registerWithProvider(server, options, callback) {}
+ static google(token) {};
/**
- * 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
+ * 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 {@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() {};
+
+ /**
+ * 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. 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) {};
+
+ /**
+ * 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 {@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.
+ * @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, providerName) {};
+
+ /**
+ * 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 {@linkcode Realm.Sync.User.login|User.login}.
+ */
+ 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.
+ */
+ get identityProvider() {};
+
+ /**
+ * Gets the access token.
+ * @returns {string}
+ */
+ get token() {};
+
+ /**
+ * Gets additional user information associated with the credentials.
+ * @returns {object} A dictionary, containing the additional information.
*/
- static register(server, username, password, callback) {}
+ get userInfo() {};
+}
+
+/**
+ * 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 {@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) {}
/**
* Request a password reset email to be sent to a user's email.
@@ -361,11 +423,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.
@@ -385,18 +447,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) {}
-
- /**
- * 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) {}
+ static confirmEmail(server, confirmationToken) {}
/**
* Creates a new sync user instance from the serialized representation.
@@ -483,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",
@@ -549,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) {}
+
+ /**
+ * @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) {}
+
+ /**
+ * @deprecated to be removed in future versions. Use User.login(server, Credentials.SOME-PROVIDER) instead.
+ */
+ static authenticate(server, provider, options) {}
}
/**
@@ -806,7 +881,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
@@ -886,7 +961,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/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 931eb234f9..034eb975ae 100644
--- a/lib/index.d.ts
+++ b/lib/index.d.ts
@@ -290,6 +290,22 @@ 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, 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;
+ readonly userInfo: { [key: string]: any };
+ }
+
/**
* User
* @see { @link https://realm.io/docs/javascript/latest/api/Realm.Sync.User.html }
@@ -302,34 +318,15 @@ 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;
- 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;
@@ -344,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 7ede965b93..90f1f8f3f0 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) {
@@ -322,170 +311,183 @@ 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;
- const keys = Object.keys(allUsers);
- if (keys.length === 0) {
- return undefined;
- } else if (keys.length > 1) {
- throw new Error("Multiple users are logged in");
- }
+ 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 allUsers[keys[0]];
+ },
- return _authenticate(this, server, json, callback);
- },
+ 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);
+ }
- login(server, username, password, callback) {
- checkTypes(arguments, ['string', 'string', 'string', 'function']);
- const json = {
- provider: 'password',
- user_info: { password: password, register: false },
- data: username
- };
+ checkTypes(arguments, ['string', 'object']);
+ if (credentials.identityProvider === 'adminToken') {
+ return this._adminUser(server, credenitals.token);
+ }
- 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);
- }
+ return _authenticate(this, server, credentials);
+ },
- return _authenticate(this, server, json, callback);
- },
+ deserialize(serialized) {
+ checkObjectTypes(serialized, {
+ server: 'string',
+ identity: 'string',
+ refreshToken: 'string',
+ isAdmin: 'boolean',
+ });
- registerWithProvider(server, options, callback) {
+ return this.createUser(serialized.server, serialized.identity, serialized.refreshToken, false, serialized.isAdmin || false);
+ },
- // 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']);
- }
+ requestPasswordReset(server, email) {
+ checkTypes(arguments, ['string', 'string']);
+ const json = {
+ provider_id: email,
+ data: { action: 'reset_password' }
+ };
- let json = {
- provider: options.provider,
- data: options.providerToken,
- };
+ return _updateAccount(this, server, json);
+ },
- if (options.userInfo) {
- json.user_info = options.userInfo;
+ completePasswordReset(server, resetToken, newPassword) {
+ checkTypes(arguments, ['string', 'string']);
+ const json = {
+ data: {
+ action: 'complete_reset',
+ token: resetToken,
+ new_password: newPassword
}
+ };
+
+ 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);
+ },
- 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);
+ confirmEmail(server, confirmationToken) {
+ checkTypes(arguments, ['string', 'string']);
+ const json = {
+ data: {
+ action: 'confirm_email',
+ token: confirmationToken
}
+ };
+
+ return _updateAccount(this, server, json);
+ },
+
+ _refreshAccessToken: refreshAccessToken,
- return _authenticate(this, server, json, callback);
- },
+ // 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);
+ },
- authenticate(server, provider, options) {
- checkTypes(arguments, ['string', 'string', 'object'])
+ 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);
+ },
- var json = {}
- switch (provider.toLowerCase()) {
+ 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':
- json.provider = 'jwt'
- json.token = options.token;
+ credentials = credentialsMethods.jwt(options.token, 'jwt');
break
case 'password':
- json.provider = 'password'
- json.user_info = { password: options.password }
- json.data = options.username
+ credentials = credentialsMethods.usernamePassword(options.username, options.password);
break
default:
- Object.assign(json, options)
- json.provider = provider
- }
-
- return _authenticate(this, server, json)
- },
-
- deserialize(serialized) {
- checkObjectTypes(serialized, {
- server: 'string',
- identity: 'string',
- refreshToken: 'string',
- isAdmin: 'boolean',
- });
-
- 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
- }
- };
-
- return _updateAccount(this, server, json);
- },
+ credentials = credentialsMethods.custom(provider, options.data, options.user_info || options.userInfo);
+ break;
+ }
- _refreshAccessToken: refreshAccessToken,
+ return this.login(server, credentials);
+ },
};
-
const instanceMethods = {
logout() {
this._logout();
@@ -609,10 +611,27 @@ const instanceMethods = {
},
};
+class Credentials {
+ constructor(identityProvider, token, userInfo) {
+ this.identityProvider = identityProvider;
+ this.token = token;
+ this.userInfo = userInfo;
+ }
+
+ toJSON() {
+ return {
+ data: this.token,
+ provider: this.identityProvider,
+ 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 98d874874b..c4bc5af0c6 100644
--- a/tests/js/session-tests.js
+++ b/tests/js/session-tests.js
@@ -105,14 +105,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'
@@ -131,7 +128,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;
@@ -180,12 +177,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 },
@@ -216,13 +213,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' } }],
@@ -259,12 +254,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' } }],
@@ -310,12 +303,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 }
};
@@ -410,7 +401,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) => {
@@ -440,8 +431,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],
@@ -481,7 +473,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,
@@ -524,7 +516,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,
@@ -565,7 +557,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,
@@ -636,8 +628,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: {
@@ -703,8 +696,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: {
@@ -729,8 +723,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 = {
@@ -836,9 +831,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();
@@ -921,7 +917,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' } });
@@ -954,7 +950,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: {
@@ -963,7 +959,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) {
@@ -981,7 +977,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: {
@@ -990,7 +986,7 @@ module.exports = {
fullSynchronization: true,
}
};
-
+
Realm.open(config).then(realm => {
let callback1 = () => {
reject("Should not be called");
@@ -1015,7 +1011,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: {
@@ -1171,7 +1167,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="
+ }
+ }
+}