UNPKG

@blockv/sdk

Version:

Allows web apps to display and interact with vatoms.

427 lines (350 loc) 13.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _urlParse = _interopRequireDefault(require("url-parse")); var _User = _interopRequireDefault(require("../../../../model/User")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // // BlockV AG. Copyright (c) 2018, all rights reserved. // // Licensed under the BlockV SDK License (the "License"); you may not use this file or // the BlockV SDK except in compliance with the License accompanying it. Unless // required by applicable law or agreed to in writing, the BlockV SDK distributed under // the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF // ANY KIND, either express or implied. See the License for the specific language // governing permissions and limitations under the License. // class UserApi { constructor(bv) { this.Blockv = bv; this.client = bv.client; this.store = bv.store; this.dataPool = bv.dataPool; } /** * Registers a user on the Blockv platform. * * @param registration contains properties of the user. * Only the properties to be registered should be set. * @return new Observable<User> instance */ getAccessToken() { return this.store.token; } setAccessToken(token) { this.store.token = ''; this.store.token = token; } getRefreshToken() { return this.store.refreshToken; } setRefreshToken(token) { this.store.token = ''; this.store.refreshToken = token; } register(registration) { return this.client.request('POST', '/v1/users', registration, false).then(data => { this.store.token = data.access_token.token; this.store.refreshToken = data.refresh_token.token; this.store.assetProvider = data.asset_provider; this.store.userID = data.user.id; this.dataPool.setSessionInfo({ userID: data.user.id }); return data; }).then(data => new _User.default(data.user)); } /** * Logs a user into the Blockv platform. Accepts a user token (phone or email). * * @param token the user's phone(E.164) or email * @param tokenType the type of the token (phone or email) * @param password the user's password. * @return JSON Object */ login(token, tokenType, password) { const payload = { token, token_type: tokenType, auth_data: { password } }; return this.client.request('POST', '/v1/user/login', payload, false).then(data => { if (!password) { const error = new Error('Login Failed, Password Reset'); error.code = 'PASSWORD_RESET'; throw error; } else { this.store.token = data.access_token.token; this.store.refreshToken = data.refresh_token.token; this.store.assetProvider = data.asset_provider; this.store.userID = data.user.id; this.dataPool.setSessionInfo({ userID: data.user.id, client: this.client }); return data; } }).then(data => new _User.default(data.user)); } /** * Logs a user into the Blockv platform. Accepts a guest id * * @param guestId the user's guest id. * @return JSON Object */ loginGuest(guestId) { const payload = { token: guestId, token_type: 'guest_id' }; return this.client.request('POST', '/v1/user/login', payload, false).then(data => { this.store.token = data.access_token.token; this.store.refreshToken = data.refresh_token.token; this.store.assetProvider = data.asset_provider; this.dataPool.setSessionInfo({ userID: data.user.id }); return data; }).then(data => new _User.default(data.user)); } uploadAvatar(request) { // get file // change to formData return this.client.request('POST', '/v1/user/avatar', request, true); } /** * Fetches the current user's profile information from the Blockv platform. * * @return JSON Object */ getCurrentUser(payload) { // get the current authenticated in user return this.client.request('GET', '/v1/user', payload, true).then(data => new _User.default(data)); } /** * Updates the current user's profile on the Blockv platform. * @param update holds the properties of the user, e.g. their first name. * Only the properties to be updated should be set. * @return JSON Object */ updateUser(update) { return this.client.request('PATCH', '/v1/user', update, true); } /** * Gets a list of the current users tokens * @return JSON Object */ getUserTokens() { return this.client.request('GET', '/v1/user/tokens', '', true); } /** * Verifies ownership of a token by submitting the verification code to the Blockv platform. * @param token the user's phone(E.164) or email * @param tokenType the type of the token (phone or email) * @param code the verification code send to the user's token (phone or email). * @return JSON Object */ verifyUserToken(verification) { return this.client.request('POST', '/v1/user/verify_token', verification, true); } /** * Sends a One-Time-Pin (OTP) to the user's token (phone or email). * This OTP may be used in place of a password to login. * @param token the user's phone(E.164) or email * @param tokenType the type of the token (phone or email) * @return JSON Object */ resetPassword(token, tokenType) { const payload = { token, token_type: tokenType }; return this.client.request('POST', '/v1/user/reset_token', payload, false); } /** * Sends a verification code to the user's token (phone or email). * This verification code should be used to verifiy the user's ownership * of the token (phone or email). * @param token the user's phone(E.164) or email * @param tokenType the type of the token (phone or email) * @return JSON Object */ sendTokenVerification(token, tokenType) { const payload = { token, token_type: tokenType }; return this.client.request('POST', '/v1/user/reset_token_verification', payload, false); } /** * Returns a server generated guest id * @return Object payload containing a guest user generated by the server */ getGuestToken() { return this.client.request('POST', '/v1/user/guest', '', false).then(data => data.properties.guest_id); } /** * Log out the current user. * The current user will not longer be authorized to perform user * scoped requests on the Blockv platfrom. * @return new JSON */ logout(params) { return this.client.request('POST', '/v1/user/logout', params, true).then(() => { this.store.token = ''; this.store.refreshToken = ''; this.dataPool.setSessionInfo(null); }).catch(err => { console.warn(err); this.store.token = ''; this.store.refreshToken = ''; this.DataPool.setSessionInfo(null); throw err; }); } static mapString(o) { return Object.keys(o).map(key => `${key}=${o[key]}`).join('&'); } encodeAssetProvider(url) { const aP = this.store.assetProvider; const aPlen = aP.length; const compare = (0, _urlParse.default)(url); for (let i = 0; i < aPlen; i += 1) { const comparethis = (0, _urlParse.default)(aP[i].uri); if (compare.hostname === comparethis.hostname) { // same uri so get the policy signature and key and append const queryString = UserApi.mapString(aP[i].descriptor); return `${url}?${queryString}`; } } return url; } addUserToken(payload) { /** * payload is * { * "token": "another.email@domain.com", * "token_type": "email", * "is_primary": false * } */ return this.client.request('POST', '/v1/user/tokens', payload, true); } setDefaultToken(tokenId) { return this.client.request('PUT', `/v1/user/tokens/${tokenId}/default`, null, true); } /** * Deletes a Users Token * @param {String} tokenId * @return {Promise<Object>} returns a success */ deleteUserToken(tokenId) { return this.client.request('DELETE', `/v1/user/tokens/${tokenId}`, null, true); } /** * Adds a redeemable the users account * @param {Object} payload Object containing the redeemable information * @return {Promise<Object>} returns a Object containing the new redeemable */ async addRedeemable(payload) { const { userID } = this.store; return this.client.request('POST', `/v1/users/${userID}/redeemables`, payload, true); } async getPublicUserProfile(userID) { return this.client.request('GET', `/v1/users/${userID}`, '', true); } /** * Logs the user in via OAuth in a browser popup window. * NOTE: This is a private method, subject to change once more OAuth flows have been fully implemented on the backend. * @private * @returns {Promise<boolean>} `true` if login completed, or `false` if login was cancelled by the user. */ async loginOAuthPopup() { // Ensure SDK has been initialized if (!this.store.appID) throw new Error('Please initialize the SDK and set your App ID first.'); // Generate random state ID const stateID = Math.random().toString(36).substr(2); // Generate the oauth URL const redirectURI = 'https://login.blockv.io/send-event.html'; const uri = `https://login.blockv.io/?response_type=code&client_id=${this.store.appID}&redirect_uri=${encodeURIComponent(redirectURI)}&scope=all&state=${stateID}`; // Create popup window const newWindow = window.open(uri, '_blank', 'left=200,top=200,width=360,height=480,chrome,centerscreen'); if (!newWindow) { throw new Error('Unable to login, popups have been blocked'); } // Create pending promise let promiseResolved = false; let promiseSuccess = null; let promiseFail = null; const promise = new Promise((resolve, reject) => { promiseSuccess = resolve; promiseFail = reject; }); // Create window close checker const closeChecker = setInterval(() => { // Check if window was closed if (!newWindow.closed) return false; // It was, cancel timer clearInterval(closeChecker); // If promise was never resolved, the user must have closed the popup before logging in. Resolve the promise. if (!promiseResolved) promiseSuccess(false); }, 250); // Create message listener const messageListener = async e => { // Ensure it's from the correct origin if (e.origin !== 'https://login.blockv.io') return false; // Ensure the state matches if (e.data.state !== stateID) return false; // Ensure the action matches if (e.data.action !== 'oauth-response') return false; console.log(e.data); // Check response type if (e.data.code) { let oauthObj = { 'grant_type': 'authorization_code', 'client_id': this.Blockv.store.appID, 'code': e.data.code, 'redirect_uri': redirectURI }; let oa = await this.Blockv.client.request('POST', 'v1/oauth/token', oauthObj, false); // We have our user data, store it this.setRefreshToken(oa.refresh_token.token); this.store.token = oa.access_token.token; // Get user info and set the store properties const profile = await this.getCurrentUser(); this.store.userID = profile.id; // Get asset provider info and store it const assetProviders = await this.client.request('GET', 'v1/user/asset_providers', null, true); this.store.assetProvider = assetProviders.asset_provider; // Inform data pool that the current user changed this.dataPool.setSessionInfo({ userID: profile.id }); // Done promiseResolved = true; promiseSuccess(true); } else { // Login failed, return error const err = new Error(e.data.error_text || 'Unable to login.'); err.code = e.data.error; promiseResolved = true; promiseFail(err); } // Cleanup, remove event listener newWindow.close(); window.removeEventListener('message', messageListener); clearInterval(closeChecker); return true; }; // Attach message listener window.addEventListener('message', messageListener); // Done, return promise return promise; } // Used for manual OAuth Login flow async loginOauthCode(redirectURI, code) { let oauthObj = { 'grant_type': 'authorization_code', 'client_id': this.store.appID, 'code': code, 'redirect_uri': redirectURI }; let oa = await this.Blockv.client.request('POST', 'v1/oauth/token', oauthObj, false); // We have our user data, store it this.setRefreshToken(oa.refresh_token.token); this.store.token = oa.access_token.token; // Get user info and set the store properties const profile = await this.getCurrentUser(); this.store.userID = profile.id; // Get asset provider info and store it const assetProviders = await this.client.request('GET', 'v1/user/asset_providers', null, true); this.store.assetProvider = assetProviders.asset_provider; // Inform data pool that the current user changed this.dataPool.setSessionInfo({ userID: profile.id }); } } exports.default = UserApi;