UNPKG

mongodb-stitch

Version:

[![Join the chat at https://gitter.im/mongodb/stitch](https://badges.gitter.im/mongodb/stitch.svg)](https://gitter.im/mongodb/stitch?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

388 lines 19.5 kB
var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "bson", "../../internal/common/StitchErrorUtils", "../../internal/net/Headers", "../../internal/net/Method", "../../internal/net/Stream", "../../internal/net/StitchAuthDocRequest", "../../internal/net/StitchAuthRequest", "../../internal/net/StitchDocRequest", "../../StitchClientError", "../../StitchClientErrorCode", "../../StitchError", "../../StitchRequestError", "../../StitchRequestErrorCode", "../../StitchServiceError", "../../StitchServiceErrorCode", "../providers/internal/StitchAuthResponseCredential", "./AccessTokenRefresher", "./AuthInfo", "./JWT", "./models/ApiAuthInfo", "./models/ApiCoreUserProfile", "./models/StoreAuthInfo"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var bson_1 = require("bson"); var StitchErrorUtils_1 = require("../../internal/common/StitchErrorUtils"); var Headers_1 = __importDefault(require("../../internal/net/Headers")); var Method_1 = __importDefault(require("../../internal/net/Method")); var Stream_1 = __importDefault(require("../../internal/net/Stream")); var StitchAuthDocRequest_1 = require("../../internal/net/StitchAuthDocRequest"); var StitchAuthRequest_1 = require("../../internal/net/StitchAuthRequest"); var StitchDocRequest_1 = require("../../internal/net/StitchDocRequest"); var StitchClientError_1 = __importDefault(require("../../StitchClientError")); var StitchClientErrorCode_1 = require("../../StitchClientErrorCode"); var StitchError_1 = __importDefault(require("../../StitchError")); var StitchRequestError_1 = __importDefault(require("../../StitchRequestError")); var StitchRequestErrorCode_1 = require("../../StitchRequestErrorCode"); var StitchServiceError_1 = __importDefault(require("../../StitchServiceError")); var StitchServiceErrorCode_1 = require("../../StitchServiceErrorCode"); var StitchAuthResponseCredential_1 = __importDefault(require("../providers/internal/StitchAuthResponseCredential")); var AccessTokenRefresher_1 = __importDefault(require("./AccessTokenRefresher")); var AuthInfo_1 = __importDefault(require("./AuthInfo")); var JWT_1 = __importDefault(require("./JWT")); var ApiAuthInfo_1 = __importDefault(require("./models/ApiAuthInfo")); var ApiCoreUserProfile_1 = __importDefault(require("./models/ApiCoreUserProfile")); var StoreAuthInfo_1 = require("./models/StoreAuthInfo"); var OPTIONS = "options"; var DEVICE = "device"; var CoreStitchAuth = (function () { function CoreStitchAuth(requestClient, authRoutes, storage, useTokenRefresher) { if (useTokenRefresher === void 0) { useTokenRefresher = true; } this.requestClient = requestClient; this.authRoutes = authRoutes; this.storage = storage; var info; try { info = StoreAuthInfo_1.readFromStorage(storage); } catch (e) { throw new StitchClientError_1.default(StitchClientErrorCode_1.StitchClientErrorCode.CouldNotLoadPersistedAuthInfo); } if (info === undefined) { this.authInfo = AuthInfo_1.default.empty(); } else { this.authInfo = info; } this.prepUser(); if (useTokenRefresher) { this.accessTokenRefresher = new AccessTokenRefresher_1.default(this); this.accessTokenRefresher.run(); } } Object.defineProperty(CoreStitchAuth.prototype, "isLoggedIn", { get: function () { return this.currentUser !== undefined; }, enumerable: true, configurable: true }); Object.defineProperty(CoreStitchAuth.prototype, "user", { get: function () { return this.currentUser; }, enumerable: true, configurable: true }); CoreStitchAuth.prototype.doAuthenticatedRequest = function (stitchReq) { var _this = this; return this.requestClient .doRequest(this.prepareAuthRequest(stitchReq)) .catch(function (err) { return _this.handleAuthFailure(err, stitchReq); }); }; CoreStitchAuth.prototype.doAuthenticatedRequestWithDecoder = function (stitchReq, decoder) { return this.doAuthenticatedRequest(stitchReq) .then(function (response) { var obj = bson_1.EJSON.parse(response.body, { strict: false }); if (decoder) { return decoder.decode(obj); } return obj; }) .catch(function (err) { throw StitchErrorUtils_1.wrapDecodingError(err); }); }; CoreStitchAuth.prototype.openAuthenticatedEventStream = function (stitchReq, open) { var _this = this; if (open === void 0) { open = true; } if (!this.isLoggedIn) { throw new StitchClientError_1.default(StitchClientErrorCode_1.StitchClientErrorCode.MustAuthenticateFirst); } var authToken; if (stitchReq.useRefreshToken) { authToken = this.authInfo.refreshToken; } else { authToken = this.authInfo.accessToken; } return this.requestClient.doStreamRequest(stitchReq.builder .withPath(stitchReq.path + "&stitch_at=" + authToken) .build(), open, function () { return _this.openAuthenticatedEventStream(stitchReq, false); }) .catch(function (err) { return _this.handleAuthFailureForEventStream(err, stitchReq, open); }); }; CoreStitchAuth.prototype.openAuthenticatedStreamWithDecoder = function (stitchReq, decoder) { return this.openAuthenticatedEventStream(stitchReq) .then(function (eventStream) { return new Stream_1.default(eventStream, decoder); }); }; CoreStitchAuth.prototype.refreshAccessToken = function () { var _this = this; var reqBuilder = new StitchAuthRequest_1.StitchAuthRequest.Builder() .withRefreshToken() .withPath(this.authRoutes.sessionRoute) .withMethod(Method_1.default.POST); return this.doAuthenticatedRequest(reqBuilder.build()).then(function (response) { try { var partialInfo = ApiAuthInfo_1.default.fromJSON(JSON.parse(response.body)); _this.authInfo = _this.authInfo.merge(partialInfo); } catch (err) { throw new StitchRequestError_1.default(err, StitchRequestErrorCode_1.StitchRequestErrorCode.DECODING_ERROR); } try { StoreAuthInfo_1.writeToStorage(_this.authInfo, _this.storage); } catch (err) { throw new StitchClientError_1.default(StitchClientErrorCode_1.StitchClientErrorCode.CouldNotPersistAuthInfo); } }); }; CoreStitchAuth.prototype.loginWithCredentialInternal = function (credential) { if (credential instanceof StitchAuthResponseCredential_1.default) { return this.processLogin(credential, credential.authInfo, credential.asLink); } if (!this.isLoggedIn) { return this.doLogin(credential, false); } if (credential.providerCapabilities.reusesExistingSession) { if (credential.providerType === this.currentUser.loggedInProviderType) { return Promise.resolve(this.currentUser); } } this.logoutInternal(); return this.doLogin(credential, false); }; CoreStitchAuth.prototype.linkUserWithCredentialInternal = function (user, credential) { if (this.currentUser !== undefined && user.id !== this.currentUser.id) { return Promise.reject(new StitchClientError_1.default(StitchClientErrorCode_1.StitchClientErrorCode.UserNoLongerValid)); } return this.doLogin(credential, true); }; CoreStitchAuth.prototype.logoutInternal = function () { var _this = this; if (!this.isLoggedIn) { return Promise.resolve(); } return this.doLogout() .then(function () { _this.clearAuth(); }) .catch(function () { _this.clearAuth(); }); }; Object.defineProperty(CoreStitchAuth.prototype, "hasDeviceId", { get: function () { return (this.authInfo.deviceId !== undefined && this.authInfo.deviceId !== "" && this.authInfo.deviceId !== "000000000000000000000000"); }, enumerable: true, configurable: true }); Object.defineProperty(CoreStitchAuth.prototype, "deviceId", { get: function () { if (!this.hasDeviceId) { return undefined; } return this.authInfo.deviceId; }, enumerable: true, configurable: true }); CoreStitchAuth.prototype.prepareAuthRequest = function (stitchReq) { if (!this.isLoggedIn) { throw new StitchClientError_1.default(StitchClientErrorCode_1.StitchClientErrorCode.MustAuthenticateFirst); } var newReq = stitchReq.builder; var newHeaders = newReq.headers || {}; if (stitchReq.useRefreshToken) { newHeaders[Headers_1.default.AUTHORIZATION] = Headers_1.default.getAuthorizationBearer(this.authInfo.refreshToken); } else { newHeaders[Headers_1.default.AUTHORIZATION] = Headers_1.default.getAuthorizationBearer(this.authInfo.accessToken); } newReq.withHeaders(newHeaders); return newReq.build(); }; CoreStitchAuth.prototype.handleAuthFailureForEventStream = function (ex, req, open) { var _this = this; if (open === void 0) { open = true; } if (!(ex instanceof StitchServiceError_1.default) || ex.errorCode !== StitchServiceErrorCode_1.StitchServiceErrorCode.InvalidSession) { throw ex; } if (req.useRefreshToken || !req.shouldRefreshOnFailure) { this.clearAuth(); throw ex; } return this.tryRefreshAccessToken(req.startedAt).then(function () { return _this.openAuthenticatedEventStream(req.builder.withShouldRefreshOnFailure(false).build(), open); }); }; CoreStitchAuth.prototype.handleAuthFailure = function (ex, req) { var _this = this; if (!(ex instanceof StitchServiceError_1.default) || ex.errorCode !== StitchServiceErrorCode_1.StitchServiceErrorCode.InvalidSession) { throw ex; } if (req.useRefreshToken || !req.shouldRefreshOnFailure) { this.clearAuth(); throw ex; } return this.tryRefreshAccessToken(req.startedAt).then(function () { return _this.doAuthenticatedRequest(req.builder.withShouldRefreshOnFailure(false).build()); }); }; CoreStitchAuth.prototype.tryRefreshAccessToken = function (reqStartedAt) { if (!this.isLoggedIn) { throw new StitchClientError_1.default(StitchClientErrorCode_1.StitchClientErrorCode.LoggedOutDuringRequest); } try { var jwt = JWT_1.default.fromEncoded(this.authInfo.accessToken); if (jwt.issuedAt >= reqStartedAt) { return Promise.resolve(); } } catch (e) { } return this.refreshAccessToken(); }; CoreStitchAuth.prototype.prepUser = function () { if (this.authInfo.userId !== undefined) { this.currentUser = this.userFactory.makeUser(this.authInfo.userId, this.authInfo.loggedInProviderType, this.authInfo.loggedInProviderName, this.authInfo.userProfile); } }; CoreStitchAuth.prototype.attachAuthOptions = function (authBody) { var options = {}; options[DEVICE] = this.deviceInfo; authBody[OPTIONS] = options; }; CoreStitchAuth.prototype.doLogin = function (credential, asLinkRequest) { var _this = this; return this.doLoginRequest(credential, asLinkRequest) .then(function (response) { return _this.processLoginResponse(credential, response, asLinkRequest); }) .then(function (user) { _this.onAuthEvent(); return user; }); }; CoreStitchAuth.prototype.doLoginRequest = function (credential, asLinkRequest) { var reqBuilder = new StitchDocRequest_1.StitchDocRequest.Builder(); reqBuilder.withMethod(Method_1.default.POST); if (asLinkRequest) { reqBuilder.withPath(this.authRoutes.getAuthProviderLinkRoute(credential.providerName)); } else { reqBuilder.withPath(this.authRoutes.getAuthProviderLoginRoute(credential.providerName)); } var material = credential.material; this.attachAuthOptions(material); reqBuilder.withDocument(material); if (!asLinkRequest) { return this.requestClient.doRequest(reqBuilder.build()); } var linkRequest = new StitchAuthDocRequest_1.StitchAuthDocRequest(reqBuilder.build(), reqBuilder.document); return this.doAuthenticatedRequest(linkRequest); }; CoreStitchAuth.prototype.processLogin = function (credential, newAuthInfo, asLinkRequest) { var _this = this; var oldInfo = this.authInfo; var oldUser = this.currentUser; newAuthInfo = this.authInfo.merge(new AuthInfo_1.default(newAuthInfo.userId, newAuthInfo.deviceId, newAuthInfo.accessToken, newAuthInfo.refreshToken, credential.providerType, credential.providerName, undefined)); this.authInfo = newAuthInfo; this.currentUser = this.userFactory.makeUser(this.authInfo.userId, credential.providerType, credential.providerName, undefined); return this.doGetUserProfile() .then(function (profile) { newAuthInfo = newAuthInfo.merge(new AuthInfo_1.default(newAuthInfo.userId, newAuthInfo.deviceId, newAuthInfo.accessToken, newAuthInfo.refreshToken, credential.providerType, credential.providerName, profile)); try { StoreAuthInfo_1.writeToStorage(newAuthInfo, _this.storage); } catch (err) { throw new StitchClientError_1.default(StitchClientErrorCode_1.StitchClientErrorCode.CouldNotPersistAuthInfo); } _this.authInfo = newAuthInfo; _this.currentUser = _this.userFactory.makeUser(_this.authInfo.userId, credential.providerType, credential.providerName, profile); return _this.currentUser; }) .catch(function (err) { if (asLinkRequest) { _this.authInfo = oldInfo; _this.currentUser = oldUser; } else { _this.clearAuth(); } throw err; }); }; CoreStitchAuth.prototype.processLoginResponse = function (credential, response, asLinkRequest) { try { if (!response) { throw new StitchServiceError_1.default("the login response could not be processed for credential: " + credential + ";" + "response was undefined"); } if (!response.body) { throw new StitchServiceError_1.default("response with status code " + response.statusCode + " has empty body"); } return this.processLogin(credential, ApiAuthInfo_1.default.fromJSON(JSON.parse(response.body)), asLinkRequest); } catch (err) { throw new StitchRequestError_1.default(err, StitchRequestErrorCode_1.StitchRequestErrorCode.DECODING_ERROR); } }; CoreStitchAuth.prototype.doGetUserProfile = function () { var reqBuilder = new StitchAuthRequest_1.StitchAuthRequest.Builder(); reqBuilder.withMethod(Method_1.default.GET).withPath(this.authRoutes.profileRoute); return this.doAuthenticatedRequest(reqBuilder.build()) .then(function (response) { return ApiCoreUserProfile_1.default.fromJSON(JSON.parse(response.body)); }) .catch(function (err) { if (err instanceof StitchError_1.default) { throw err; } else { throw new StitchRequestError_1.default(err, StitchRequestErrorCode_1.StitchRequestErrorCode.DECODING_ERROR); } }); }; CoreStitchAuth.prototype.doLogout = function () { var reqBuilder = new StitchAuthRequest_1.StitchAuthRequest.Builder(); reqBuilder .withRefreshToken() .withPath(this.authRoutes.sessionRoute) .withMethod(Method_1.default.DELETE); return this.doAuthenticatedRequest(reqBuilder.build()).then(function () { return; }); }; CoreStitchAuth.prototype.clearAuth = function () { if (!this.isLoggedIn) { return; } this.authInfo = this.authInfo.loggedOut(); try { StoreAuthInfo_1.writeToStorage(this.authInfo, this.storage); } catch (e) { throw new StitchClientError_1.default(StitchClientErrorCode_1.StitchClientErrorCode.CouldNotPersistAuthInfo); } this.currentUser = undefined; this.onAuthEvent(); }; CoreStitchAuth.prototype.close = function () { if (this.accessTokenRefresher) { this.accessTokenRefresher.stop(); } }; return CoreStitchAuth; }()); exports.default = CoreStitchAuth; }); //# sourceMappingURL=CoreStitchAuth.js.map