UNPKG

connect-vtexid

Version:

VTEX ID Authentication middleware for Connect

170 lines (136 loc) 5.94 kB
### Module dependencies. ### NodeCache = require 'node-cache' request = require 'request' fs = require 'fs' colors = require 'colors' url = require 'url' WhiteList = require '../libs/white-list' Logger = require '../libs/logger' getRedirectSettings = require '../libs/return-url' parseCookies = require '../libs/cookie-parser' redirect = require '../libs/redirect' httpErrorResponse = require '../libs/http-errors' base64 = require '../libs/base64' migratedAccounts = ["iam"] authenticationHandler = (options = {}) -> FIVE_MINUTES = 5 * 60 options.verbose or= false options.ttl or= FIVE_MINUTES options.redirectUrl or= '/admin/login/?ReturnUrl=' options.logoutUrl or= '/admin/logout' options.replaceWhiteList or= false options.addToWhiteList or= [] options.useReturnUrl = true if not options.returnUrl? options.verbose or= false options.verbosityLevel = 1 if not options.verbosityLevel? options.migrationEndPoint or= 'https://accounts.vtex.com/index.html#/' logger = new Logger(options) logger.logConfigOptions() logger.logWhiteListProcedure() whiteList = new WhiteList options.replaceWhiteList whiteList.addToPublicUris options.redirectUrl whiteList.addToPublicUris options.addToWhiteList logger.logWhiteListConfiguration(whiteList) logger.logCacheSetupProcedure() cache = new NodeCache stdTTL: options.ttl (req, res, next) -> req.vtex or= {} unauthorized = httpErrorResponse res, 401 # Bypasses authentication if requesting public resource if whiteList.isInWhiteList(req.url) and req.url.indexOf(options.logoutUrl) is -1 logger.logWhiteListHit(req.url) return next() # Gets VTEX ID Return Url logger.logRedirectUrlSetupProcedure() redirectSettings = getRedirectSettings options, req.url logger.logRedirectUrl(redirectSettings.redirectUrl) # Parses cookies from request logger.logCookieParsingProcedure() req.cookies = parseCookies req # Let user go to logout page if req.url.indexOf(options.logoutUrl) isnt -1 and req.cookies.VtexIdclientAutCookie? logger.logUserLogout() urlParams = url.parse(req.url, true) if req.headers.originalHost? referer = req.vtex.store + ".vtexlocal.com.br" else referer = req.headers.host refererRegexp = /([a-zA-Z0-9-$_.+]*)/ match = refererRegexp.exec(referer) domain = match[1] expiredDate = new Date() expiredDate.setYear(2000) expiredCookieName = "VtexIdclientAutCookie=" expiredDomain = "domain=#{domain}" expiredDottedDomain = "domain=.#{domain}" expiredDate = "expires=#{expiredDate.toUTCString()}" expiredPath = "path=/" expired = "#{expiredCookieName}; #{expiredDomain}; #{expiredDate}; #{expiredPath}" expiredDotted = "#{expiredCookieName}; #{expiredDottedDomain}; #{expiredDate}; #{expiredPath}" expiredWithoutDomain = "#{expiredCookieName}; #{expiredDate}; #{expiredPath}" res.setHeader('Set-Cookie', expiredWithoutDomain) res.setHeader('Set-Cookie', expiredDotted) res.setHeader('Set-Cookie', expired) urlToRedirect = encodeURIComponent( urlParams.query.redirectUrl or "http://" + referer + urlParams.query.previousUrl or "http://" + referer + redirectSettings.redirectUrl ) targetUrl = "https://vtexid.vtex.com.br/VtexIdAuthSite/Logout.aspx?urlToRedirect=#{urlToRedirect}" return redirect(res, targetUrl) # Gets token from header in CORS if req.headers and req.headers.vtexidclientautcookie req.cookies.VtexIdclientAutCookie = req.headers.vtexidclientautcookie logger.logCookies(req.cookies) # Redirects to login page if user does not have vtex id cookie if not req.cookies.VtexIdclientAutCookie logger.logCookieNotFound() if (req.vtex.store && (req.vtex.store in migratedAccounts)) if req.query.ott return next() fullUrl = 'https://' + req.host + req.originalUrl; redirectUri = base64.encode fullUrl redirectUrl = options.migrationEndPoint + req.vtex.store + "/?redirectUri=" + redirectUri else redirectUrl = redirectSettings.redirectUrl return redirect res, redirectUrl # Checks if vtex id auth info is already cached logger.logCacheCheck() cache.get req.cookies.VtexIdclientAutCookie, (err, value) -> return next(err) if err if value[req.cookies.VtexIdclientAutCookie] vtexIdData = value[req.cookies.VtexIdclientAutCookie] logger.logCachedUser(vtexIdData.user) req.vtex.vtexIdData = vtexIdData req.vtex.vtexIdData.fromCache = true return next() else logger.logApiRequest() vtexIdEndpoint = "https://vtexid.vtex.com.br/api/vtexid/pub/authenticated/user?authToken=" urlEncodedAuthCookie = encodeURIComponent(req.cookies.VtexIdclientAutCookie) return request.get (vtexIdEndpoint + urlEncodedAuthCookie), (err, response, body) -> unless body? and body.length > 0 logger.logRedirectToLoginPage() return redirect(res, options.logoutUrl, req.url) try body = JSON.parse(body) logger.logApiResponseCode(response.statusCode) unless body? logger.logRedirectToLoginPage() return redirect(res, options.logoutUrl, req.url) if body.error logger.logRedirectToLoginPage() return redirect(res, options.logoutUrl, req.url) unless body.user? logger.logUnauthorizedUser() return unauthorized(body) logger.logCachingUser(body.user) cache.set req.cookies.VtexIdclientAutCookie, body req.vtex.vtexIdData = body req.vtex.vtexIdData.fromCache = false next() catch e return next(e) module.exports = authenticationHandler