├── .travis.yml ├── Block ├── Auth0.php └── Auth0 │ └── Dashboard │ └── Info.php ├── Console └── Command │ └── Auth0Sync.php ├── Controller └── Auth0 │ ├── Callback.php │ ├── Edit.php │ ├── ForgotPassword.php │ ├── Login.php │ └── Register.php ├── Helper └── Data.php ├── Logger └── Handler.php ├── Model ├── Auth0 │ ├── Api.php │ └── Config.php └── Config │ └── Source │ ├── Auth0 │ └── Algorithm.php │ └── Provider.php ├── Observer └── Auth0 │ └── RemoveAuthorizationLinks.php ├── README.MD ├── composer.json ├── etc ├── acl.xml ├── adminhtml │ └── system.xml ├── config.xml ├── di.xml ├── frontend │ ├── di.xml │ ├── events.xml │ └── routes.xml └── module.xml ├── registration.php └── view └── frontend ├── layout └── default.xml ├── requirejs-config.js ├── templates └── auth0 │ ├── dashboard │ └── info.phtml │ └── link │ └── login.phtml └── web └── js ├── libs ├── auth0-lock.min.js └── auth0.min.js └── magefox.auth0.js /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | sudo: false 4 | 5 | php: 6 | - 7.0 7 | - 7.1 8 | 9 | install: 10 | - wget https://gist.githubusercontent.com/cdiacon/457f0e09fb936e5cc859/raw/a9d46ee07b550b9a742a3cb418c28b5d49b1753b/auth.json 11 | - composer install --prefer-dist 12 | 13 | script: 14 | - php vendor/bin/phpcs --standard=PSR2 Block/ Console/ Controller/ Helper/ Logger/ Model/ Observer/ 15 | - php vendor/bin/phpmd Block/,Console/,Controller/,Helper/,Logger/,Model/,Observer/ text cleancode,codesize,controversial,design,naming,unusedcode 16 | - php vendor/bin/phpcpd Block/ Console/ Controller/ Helper/ Logger/ Model/ Observer/ 17 | 18 | after_script: 19 | - php vendor/bin/coveralls -------------------------------------------------------------------------------- /Block/Auth0.php: -------------------------------------------------------------------------------- 1 | config = $config; 30 | $this->formKey = $formKey; 31 | 32 | parent::__construct($context, $data); 33 | } 34 | 35 | /** 36 | * Get auth0 configurations 37 | * 38 | * @return \Magefox\SSOIntegration\Model\Auth0\Config 39 | */ 40 | public function getConfig() 41 | { 42 | return $this->config; 43 | } 44 | 45 | /** 46 | * Get form key 47 | * 48 | * @return string 49 | */ 50 | public function getFormKey() 51 | { 52 | return $this->formKey->getFormKey(); 53 | } 54 | 55 | /** 56 | * Get logo src 57 | * 58 | * @return string 59 | * @throws \Magento\Framework\Exception\LocalizedException 60 | */ 61 | public function getLogoSrc() 62 | { 63 | return $this->getLayout()->getBlock('logo')->getLogoSrc(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Block/Auth0/Dashboard/Info.php: -------------------------------------------------------------------------------- 1 | config = $config; 33 | $this->formKey = $formKey; 34 | 35 | parent::__construct($context, $currentCustomer, $subscriberFactory, $helperView, $data); 36 | } 37 | 38 | /** 39 | * Get auth0 configurations 40 | * 41 | * @return \Magefox\SSOIntegration\Model\Auth0\Config 42 | */ 43 | public function getConfig() 44 | { 45 | return $this->config; 46 | } 47 | 48 | /** 49 | * Get form key 50 | * 51 | * @return string 52 | */ 53 | public function getFormKey() 54 | { 55 | return $this->formKey->getFormKey(); 56 | } 57 | 58 | /** 59 | * Get logo src 60 | * 61 | * @return string 62 | * @throws \Magento\Framework\Exception\LocalizedException 63 | */ 64 | public function getLogoSrc() 65 | { 66 | return $this->getLayout()->getBlock('logo')->getLogoSrc(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Console/Command/Auth0Sync.php: -------------------------------------------------------------------------------- 1 | appState = $appState; 62 | $this->confirmationQuestionFactory = $confirmationQuestionFactory; 63 | $this->progressBarFactory = $progressBarFactory; 64 | $this->customerCollectionFactory = $customerCollectionFactory; 65 | $this->customerRegistry = $customerRegistry; 66 | $this->apiFactory = $apiFactory; 67 | 68 | parent::__construct(); 69 | } 70 | 71 | /** 72 | * Configure command options 73 | */ 74 | protected function configure() 75 | { 76 | $this->setName(self::COMMAND)->setDescription('Sync magento users to Auth0.'); 77 | 78 | parent::configure(); 79 | } 80 | 81 | /** 82 | * Execute command 83 | * 84 | * @param InputInterface $input 85 | * @param OutputInterface $output 86 | * @return int|null 87 | * @throws \Magento\Framework\Exception\LocalizedException 88 | */ 89 | protected function execute(InputInterface $input, OutputInterface $output) 90 | { 91 | $helper = $this->getHelper('question'); 92 | $question = $this->confirmationQuestionFactory->create([ 93 | 'question' => '' . 94 | 'Sync customers to Auth0, Your customers will have to change password manually. ' . 95 | 'Are you sure? (Yes/No):' . 96 | ' ', 97 | 'default' => false 98 | ]); 99 | 100 | if (!$helper->ask($input, $output, $question)) { 101 | return null; 102 | } 103 | 104 | $this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); 105 | $output->setDecorated(true); 106 | 107 | $customerIds = $this->customerCollectionFactory 108 | ->create() 109 | ->getAllIds(); 110 | 111 | $progress = $this->progressBarFactory->create([ 112 | 'output' => $output, 113 | 'max' => count($customerIds) 114 | ]); 115 | 116 | $progress->setFormat( 117 | "Syncing customers to Auth0 " . 118 | "%current%/%max% [%bar%] %percent:3s%% %elapsed%\n" 119 | ); 120 | 121 | try { 122 | foreach ($customerIds as $customerId) { 123 | /** 124 | * @var $customer \Magento\Customer\Model\Customer 125 | */ 126 | $customer = $this->customerRegistry->retrieve($customerId); 127 | $data = [ 128 | "name" => $customer->getFirstname(), 129 | "email" => $customer->getEmail(), 130 | "password" => $customer->getPasswordHash(), 131 | "email_verified" => true, 132 | "user_metadata" => [ 133 | "firstname" => $customer->getFirstname(), 134 | "lastname" => $customer->getLastname() 135 | ], 136 | "connection" => "Username-Password-Authentication" 137 | ]; 138 | 139 | /** 140 | * Response 'statusCode' is 409 if "User already exists" 141 | */ 142 | $this->apiFactory->create() 143 | ->createUser($data); 144 | 145 | $progress->advance(); 146 | } 147 | } catch (\Exception $e) { 148 | $output->writeln("{$e->getMessage()}"); 149 | return \Magento\Framework\Console\Cli::RETURN_FAILURE; 150 | } 151 | 152 | $output->write("\n"); 153 | return \Magento\Framework\Console\Cli::RETURN_SUCCESS; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /Controller/Auth0/Callback.php: -------------------------------------------------------------------------------- 1 | dataObjectHelper = $dataObjectHelper; 75 | $this->apiFactory = $apiFactory; 76 | $this->storeManager = $storeManager; 77 | $this->customerFactory = $customerFactory; 78 | $this->customerDataFactory = $customerDataFactory; 79 | $this->formValidator = $formValidator; 80 | $this->accountManagement = $accountManagement; 81 | $this->customerSession = $customerSession; 82 | 83 | parent::__construct($context); 84 | } 85 | 86 | /** 87 | * Execute action 88 | * 89 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void 90 | * @throws \Magento\Framework\Exception\LocalizedException 91 | */ 92 | public function execute() 93 | { 94 | $this->getRequest()->setParams( 95 | [ 96 | 'form_key' => $this->getRequest()->getParam('state') 97 | ] 98 | ); 99 | 100 | /** 101 | * Validate form key 102 | */ 103 | if ($this->formValidator->validate($this->getRequest())) { 104 | try { 105 | /** 106 | * @var $api \Magefox\SSOIntegration\Model\Auth0\Api 107 | */ 108 | $api = $this->apiFactory->create(); 109 | $user = $api->getUser($this->getRequest()->getParam('code')); 110 | 111 | /** 112 | * @var $customer \Magento\Customer\Model\Customer 113 | */ 114 | $customer = $this->customerFactory 115 | ->create() 116 | ->setWebsiteId($this->storeManager->getStore()->getWebsiteId()) 117 | ->loadByEmail($user['email']); 118 | 119 | /** 120 | * Customer register 121 | */ 122 | if (!$customer->getId()) { 123 | $customer = $this->customerDataFactory->create(); 124 | $this->dataObjectHelper->populateWithArray( 125 | $customer, 126 | [ 127 | 'firstname' => $user['user_metadata']['firstname'], 128 | 'lastname' => $user['user_metadata']['lastname'], 129 | 'email' => $user['email'] 130 | ], 131 | \Magento\Customer\Api\Data\CustomerInterface::class 132 | ); 133 | 134 | $customer = $this->accountManagement 135 | ->createAccount($customer, $user['user_id'], ''); 136 | 137 | $this->_eventManager->dispatch( 138 | 'customer_register_success', 139 | ['account_controller' => $this, 'customer' => $customer] 140 | ); 141 | } 142 | 143 | /** 144 | * Process login 145 | */ 146 | if (!$user['email_verified']) { 147 | $this->messageManager->addWarningMessage( 148 | __('You must confirm your account. Please check your email for the confirmation link.') 149 | ); 150 | $this->_redirect('/'); 151 | return; 152 | } else { 153 | $this->customerSession->loginById($customer->getId()); 154 | } 155 | 156 | $this->messageManager->addSuccessMessage(__('Login successful.')); 157 | $this->_redirect('/'); 158 | return; 159 | } catch (\Exception $e) { 160 | $this->messageManager->addErrorMessage($e->getMessage()); 161 | $this->_redirect('/'); 162 | return; 163 | } 164 | } else { 165 | $this->messageManager->addErrorMessage(__('Invalid form key, please try again.')); 166 | $this->_redirect('/'); 167 | return; 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /Controller/Auth0/Edit.php: -------------------------------------------------------------------------------- 1 | scopeConfig = $scopeConfig; 46 | $this->resultForwardFactory = $resultForwardFactory; 47 | 48 | parent::__construct($context, $customerSession, $resultPageFactory); 49 | } 50 | 51 | /** 52 | * Forward to 404 53 | * 54 | * @return \Magento\Framework\Controller\Result\Forward|\Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page 55 | */ 56 | public function execute() 57 | { 58 | $active = $this->scopeConfig->getValue( 59 | 'sso_integration/general/active', 60 | \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE 61 | ); 62 | 63 | if ($active) { 64 | $forwarder = $this->resultForwardFactory->create(); 65 | $forwarder->forward('noroute'); 66 | 67 | return $forwarder; 68 | } else { 69 | return parent::execute(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Controller/Auth0/ForgotPassword.php: -------------------------------------------------------------------------------- 1 | scopeConfig = $scopeConfig; 46 | $this->resultForwardFactory = $resultForwardFactory; 47 | 48 | parent::__construct($context, $customerSession, $resultPageFactory); 49 | } 50 | 51 | /** 52 | * Forward to 404 53 | * 54 | * @return \Magento\Framework\Controller\Result\Forward|\Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page 55 | */ 56 | public function execute() 57 | { 58 | $active = $this->scopeConfig->getValue( 59 | 'sso_integration/general/active', 60 | \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE 61 | ); 62 | 63 | if ($active) { 64 | $forwarder = $this->resultForwardFactory->create(); 65 | $forwarder->forward('noroute'); 66 | 67 | return $forwarder; 68 | } else { 69 | return parent::execute(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Controller/Auth0/Login.php: -------------------------------------------------------------------------------- 1 | scopeConfig = $scopeConfig; 46 | $this->resultForwardFactory = $resultForwardFactory; 47 | 48 | parent::__construct($context, $customerSession, $resultPageFactory); 49 | } 50 | 51 | /** 52 | * Forward to 404 53 | * 54 | * @return \Magento\Framework\Controller\Result\Forward|\Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page 55 | */ 56 | public function execute() 57 | { 58 | $active = $this->scopeConfig->getValue( 59 | 'sso_integration/general/active', 60 | \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE 61 | ); 62 | 63 | if ($active) { 64 | $forwarder = $this->resultForwardFactory->create(); 65 | $forwarder->forward('noroute'); 66 | 67 | return $forwarder; 68 | } else { 69 | return parent::execute(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Controller/Auth0/Register.php: -------------------------------------------------------------------------------- 1 | scopeConfig = $scopeConfig; 46 | $this->resultForwardFactory = $resultForwardFactory; 47 | 48 | parent::__construct($context, $customerSession, $resultPageFactory); 49 | } 50 | 51 | /** 52 | * Forward to 404 53 | * 54 | * @return \Magento\Framework\Controller\Result\Forward|\Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page 55 | */ 56 | public function execute() 57 | { 58 | $active = $this->scopeConfig->getValue( 59 | 'sso_integration/general/active', 60 | \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE 61 | ); 62 | 63 | if ($active) { 64 | $forwarder = $this->resultForwardFactory->create(); 65 | $forwarder->forward('noroute'); 66 | 67 | return $forwarder; 68 | } else { 69 | return parent::execute(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Helper/Data.php: -------------------------------------------------------------------------------- 1 | scopeConfig = $scopeConfig; 26 | 27 | parent::__construct($context); 28 | } 29 | 30 | /** 31 | * Is module active 32 | * 33 | * @return bool 34 | */ 35 | public function isActive() 36 | { 37 | return (bool) $this->scopeConfig->getValue('sso_integration/general/active', ScopeInterface::SCOPE_WEBSITE); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Logger/Handler.php: -------------------------------------------------------------------------------- 1 | config = $config; 63 | $this->curlClient = $curlClient; 64 | $this->logger = $logger; 65 | $this->serializer = $serializer; 66 | } 67 | 68 | /** 69 | * Init client access token 70 | * 71 | * @return string 72 | */ 73 | public function getAppToken() 74 | { 75 | if (!$this->appToken) { 76 | try { 77 | $this->curlClient->post( 78 | "https://{$this->config->getDomain()}/oauth/token", 79 | [ 80 | 'client_id' => $this->config->getClientId(), 81 | 'client_secret' => $this->config->getClientSecret(), 82 | 'audience' => "https://{$this->config->getDomain()}/api/v2/", 83 | 'grant_type' => 'client_credentials' 84 | ] 85 | ); 86 | 87 | $response = $this->serializer->unserialize($this->curlClient->getBody()); 88 | 89 | $this->appToken = $response['access_token']; 90 | } catch (\Exception $e) { 91 | $this->logger->debug("getClientToken error: {$e->getMessage()}"); 92 | } 93 | } 94 | 95 | return $this->appToken; 96 | } 97 | 98 | /** 99 | * Convert a certificate to PEM format 100 | * 101 | * @param string $cert - certificate, like from .well-known/jwks.json 102 | * @return string 103 | */ 104 | protected function convertCertToPem($cert) 105 | { 106 | return '-----BEGIN CERTIFICATE-----' . PHP_EOL 107 | . chunk_split($cert, 64, PHP_EOL) 108 | . '-----END CERTIFICATE-----' . PHP_EOL; 109 | } 110 | 111 | /** 112 | * Get JWT key 113 | * 114 | * @return array 115 | */ 116 | protected function getJWTKey() 117 | { 118 | if (!$this->jwtKey) { 119 | $endpoint = "https://{$this->config->getDomain()}/.well-known/jwks.json"; 120 | $jwtKey = []; 121 | 122 | try { 123 | $this->curlClient->get($endpoint); 124 | $jwks = $this->serializer->unserialize($this->curlClient->getBody()); 125 | foreach ($jwks['keys'] as $key) { 126 | $jwtKey[$key['kid']] = self::convertCertToPem($key['x5c'][0]); 127 | } 128 | } catch (\Exception $e) { 129 | $this->logger->debug("getJWTKey error: {$e->getMessage()}"); 130 | } 131 | 132 | $this->jwtKey = $jwtKey; 133 | } 134 | 135 | return $this->jwtKey; 136 | } 137 | 138 | /** 139 | * Get token 140 | * 141 | * @param string $code 142 | * @return \stdClass|bool 143 | */ 144 | protected function getRequestToken($code) 145 | { 146 | try { 147 | $this->curlClient->post( 148 | "https://{$this->config->getDomain()}/oauth/token", 149 | [ 150 | 'client_id' => $this->config->getClientId(), 151 | 'client_secret' => $this->config->getClientSecret(), 152 | 'redirect_uri' => $this->config->getCallbackUrl(), 153 | 'code' => $code, 154 | 'grant_type' => 'authorization_code' 155 | ] 156 | ); 157 | } catch (\Exception $e) { 158 | $this->logger->debug("getRequestToken error: {$e->getMessage()} with code \"{$code}\""); 159 | } 160 | 161 | $token = $this->serializer->unserialize($this->curlClient->getBody()); 162 | 163 | if (isset($token['id_token'])) { 164 | /** 165 | * Allows a 5 second tolerance on timing checks. 166 | * 167 | * Fix slight skew between the clock on the server that mints the tokens 168 | * and the clock on the server that's validating the token. 169 | */ 170 | JWT::$leeway = 5; 171 | 172 | $clientSecret = $this->config->getClientSecret(); 173 | 174 | if ($this->config->isClientSecretBase64Encoded()) { 175 | $clientSecret = JWT::urlsafeB64Decode($this->config->getClientSecret()); 176 | } 177 | 178 | $key = $this->config->getClientSigningAlgorithm() === 'RS256' ? $this->getJWTKey() : $clientSecret; 179 | 180 | // Decode the incoming ID token for the Auth0 user. 181 | return JWT::decode( 182 | $token['id_token'], 183 | $key, 184 | [$this->config->getClientSigningAlgorithm()] 185 | ); 186 | } 187 | 188 | return false; 189 | } 190 | 191 | /** 192 | * @param string $code 193 | * @return array 194 | */ 195 | public function getUser($code) 196 | { 197 | $token = $this->getRequestToken($code); 198 | $headers = [ 199 | "Authorization" => "Bearer {$this->getAppToken()}", 200 | ]; 201 | 202 | try { 203 | if ($token !== false) { 204 | $this->curlClient->setHeaders($headers); 205 | $this->curlClient->get("https://{$this->config->getDomain()}/api/v2/users/{$token->sub}"); 206 | 207 | return $this->serializer->unserialize($this->curlClient->getBody()); 208 | } else { 209 | return []; 210 | } 211 | } catch (\Exception $e) { 212 | $this->logger->debug("getUser error: {$e->getMessage()} with user_id \"{$token->sub}\""); 213 | } 214 | } 215 | 216 | /** 217 | * Create auth0 user 218 | * 219 | * @param array $data 220 | * @return array 221 | */ 222 | public function createUser(array $data) 223 | { 224 | $headers = [ 225 | "Authorization" => "Bearer {$this->getAppToken()}", 226 | "content-type" => "application/json" 227 | ]; 228 | 229 | try { 230 | $this->curlClient->setHeaders($headers); 231 | $this->curlClient->post( 232 | "https://{$this->config->getDomain()}/api/v2/users", 233 | $this->serializer->serialize($data) 234 | ); 235 | 236 | return $this->serializer->unserialize($this->curlClient->getBody()); 237 | } catch (\Exception $e) { 238 | $this->logger->debug( 239 | "createUser error: {$e->getMessage()} " . 240 | "with data \"{$this->serializer->serialize($data)}\"" 241 | ); 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /Model/Auth0/Config.php: -------------------------------------------------------------------------------- 1 | scopeConfig = $scopeConfig; 76 | $this->encryptor = $encryptor; 77 | $this->urlBuilder = $urlBuilder; 78 | } 79 | 80 | /** 81 | * Get auth0 domain 82 | * 83 | * @return string 84 | */ 85 | public function getDomain() 86 | { 87 | if (!$this->domain) { 88 | $this->domain = "{$this->scopeConfig->getValue(self::XML_PATH_ACCOUNT)}.auth0.com"; 89 | } 90 | 91 | return $this->domain; 92 | } 93 | 94 | /** 95 | * Get auth0 client id 96 | * 97 | * @return string 98 | */ 99 | public function getClientId() 100 | { 101 | if (!$this->clientId) { 102 | $this->clientId = $this->encryptor->decrypt($this->scopeConfig->getValue(self::XML_PATH_CLIENT_ID)); 103 | } 104 | 105 | return $this->clientId; 106 | } 107 | 108 | /** 109 | * Get auth0 client secret 110 | * 111 | * @return string 112 | */ 113 | public function getClientSecret() 114 | { 115 | if (!$this->clientSecret) { 116 | $this->clientSecret = $this->encryptor->decrypt($this->scopeConfig->getValue(self::XML_PATH_CLIENT_SECRET)); 117 | } 118 | 119 | return $this->clientSecret; 120 | } 121 | 122 | /** 123 | * Get callback url 124 | * 125 | * @return string 126 | */ 127 | public function getCallbackUrl() 128 | { 129 | return $this->urlBuilder->getUrl('sso/auth0/callback'); 130 | } 131 | 132 | /** 133 | * Is client secret base64 encoded 134 | * 135 | * @return bool 136 | */ 137 | public function isClientSecretBase64Encoded() 138 | { 139 | if ($this->clientSecretBase64Encoded === null) { 140 | $this->clientSecretBase64Encoded = boolval( 141 | $this->scopeConfig->getValue(self::XML_PATH_CLIENT_SECRET_BASE64_ENCODED) 142 | ); 143 | } 144 | 145 | return $this->clientSecretBase64Encoded; 146 | } 147 | 148 | /** 149 | * Get client signing Algorithm 150 | * 151 | * @return string 152 | */ 153 | public function getClientSigningAlgorithm() 154 | { 155 | if (!$this->clientSigningAlgorithm) { 156 | $this->clientSigningAlgorithm = $this->scopeConfig->getValue(self::XML_PATH_CLIENT_SIGNING_ALGORITHM); 157 | } 158 | 159 | return $this->clientSigningAlgorithm; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /Model/Config/Source/Auth0/Algorithm.php: -------------------------------------------------------------------------------- 1 | __('HS256'), 22 | 'RS256' => __('RS256') 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Model/Config/Source/Provider.php: -------------------------------------------------------------------------------- 1 | __('Auth0'), 22 | 'saml2' => __('SAML2 (Coming soon)') 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Observer/Auth0/RemoveAuthorizationLinks.php: -------------------------------------------------------------------------------- 1 | helper = $helper; 25 | } 26 | 27 | /** 28 | * Fires when layout_generate_blocks_after is dispatched 29 | * 30 | * @param Observer $observer 31 | * @throws \Magento\Framework\Exception\LocalizedException 32 | */ 33 | public function execute(Observer $observer) 34 | { 35 | /** 36 | * @var $layout \Magento\Framework\View\Layout 37 | */ 38 | $layout = $observer->getLayout(); 39 | $active = $this->helper->isActive(); 40 | $loginLink = $layout->getBlock('authorization-link-login'); 41 | $registerLink = $layout->getBlock('register-link'); 42 | $accountInformationLink = $layout->getBlock('customer-account-navigation-account-edit-link'); 43 | 44 | if ($loginLink && $active) { 45 | $layout->unsetElement('authorization-link-login'); 46 | } 47 | 48 | if ($registerLink && $active) { 49 | $layout->unsetElement('register-link'); 50 | } 51 | 52 | if ($accountInformationLink && $accountInformationLink) { 53 | $layout->unsetElement('customer-account-navigation-account-edit-link'); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Magento 2 SSO Integration 2 | [![Join the chat at https://gitter.im/magefox/sso-integration](https://badges.gitter.im/magefox/sso-integration.svg)](https://gitter.im/magefox/sso-integration?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 3 | [![Build Status](https://img.shields.io/travis/magefox/sso-integration.svg?style=flat)](https://travis-ci.org/magefox/sso-integration) 4 | [![Latest Stable Version](https://poser.pugx.org/magefox/sso-integration/v/stable)](https://packagist.org/packages/magefox/sso-integration) 5 | [![Total Downloads](https://poser.pugx.org/magefox/sso-integration/downloads)](https://packagist.org/packages/magefox/sso-integration) 6 | [![Software License](https://img.shields.io/badge/license-GPL-green.svg?style=flat)](http://opensource.org/licenses/gpl-2.0.php) 7 | ## Description 8 | Single Sign On (SSO) Integrations which includes [Auth0](https://auth0.com), SAML2 protocol(Coming Soon) enable the use of external services for single sign-on. 9 | 10 | 11 | ## Features 12 | - 100% open source. 13 | - Easily switch On/Off the Module. 14 | - Supports Single Sign On (IdP and SP initiated) 15 | - Supports Magento Multi-stores. 16 | - Supported 3 party services: [Auth0](https://auth0.com), SAML2 Protocol (Coming soon) 17 | 18 | ### Auth0 19 | - Use auth0-lock js framework to login. 20 | - Command line to sync existed customers to Auth0 service. 21 | ``` 22 | bin/magento sso:auth0:sync 23 | ``` 24 | 25 | ## Installation 26 | ### Manual (without composer) 27 | - Download zip file of thelast version of this extension under release tab 28 | - Extract files in the Magento root directory in the folder app/code/Magefox/SSOIntegration 29 | - Enable the extension 30 | ``` 31 | php bin/magento --clear-static-content module:enable Magefox_SSOIntegration 32 | ``` 33 | - Upgrade Magento setup 34 | ``` 35 | php bin/magento setup:upgrade 36 | ``` 37 | 38 | ### With Composer 39 | In the Magento root directory 40 | - Install the module 41 | ``` 42 | composer require magefox/sso-integration 43 | php bin/magento module:enable Magefox_SSOIntegration 44 | php bin/magento setup:upgrade 45 | ``` 46 | 47 | ### Cleaning 48 | - Upgrade Magento setup 49 | ``` 50 | php bin/magento setup:upgrade 51 | ``` 52 | - Clear cache 53 | ``` 54 | php bin/magento cache:flush 55 | ``` 56 | 57 | ## Settings 58 | The Settings of the extension are available at Stores > Configuration. At the Magefox tab, the "SSO integration" link. 59 | 60 | There you will be able to fill several sections: 61 | - **Status**. To enable or disable the extension. 62 | - **Provider**. Select provider Which you will be use (ex: [Auth0](https://auth0.com)). 63 | - And another options depend your provider you selected. 64 | 65 | ## Release Notes 66 | ### 1.0.0 67 | * Initial version. 68 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "magefox/sso-integration", 3 | "description": "A Magento 2 SSO Integration module.", 4 | "type": "magento2-module", 5 | "version": "1.0.1", 6 | "license": "MIT", 7 | "repositories": [ 8 | { 9 | "type": "composer", 10 | "url": "https://repo.magento.com/" 11 | } 12 | ], 13 | "require": { 14 | "magento/module-customer": "^101.0", 15 | "firebase/php-jwt": "^5.0", 16 | "simplesamlphp/saml2": "^3.1" 17 | }, 18 | "require-dev": { 19 | "phpunit/phpunit": "^6.2", 20 | "phpmd/phpmd": "@stable", 21 | "magento/marketplace-eqp": "@stable", 22 | "squizlabs/php_codesniffer": "@stable", 23 | "sebastian/phpcpd": "@stable", 24 | "satooshi/php-coveralls": "^1.1" 25 | }, 26 | "authors": [ 27 | { 28 | "name": "Magefox", 29 | "email": "magefoxtech@gmail.com" 30 | }, 31 | { 32 | "name": "Kend", 33 | "email": "vanthinh87@gmail.com" 34 | } 35 | ], 36 | "autoload": { 37 | "files": [ "registration.php" ], 38 | "psr-4": { 39 | "Magefox\\SSOIntegration\\": "" 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /etc/acl.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /etc/adminhtml/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | separator-top 17 | 18 | magefox 19 | Magefox_SSOIntegration::configurations 20 | 21 | 22 | 23 | 24 | Magento\Config\Model\Config\Source\Yesno 25 | 26 | 27 | 28 | Magefox\SSOIntegration\Model\Config\Source\Provider 29 | 30 | 31 | 32 | required-entry 33 | Auth0 Account. eg. the account for this domain: gloong.auth0.com is gloong 34 | 35 | auth0 36 | 37 | 38 | 39 | 40 | Magento\Config\Model\Config\Backend\Encrypted 41 | required-entry 42 | Auth0 dashboard.]]> 43 | 44 | auth0 45 | 46 | 47 | 48 | 49 | Magento\Config\Model\Config\Backend\Encrypted 50 | required-entry 51 | Auth0 dashboard.]]> 52 | 53 | auth0 54 | 55 | 56 | 57 | 58 | Magento\Config\Model\Config\Source\Yesno 59 | 60 | 61 | auth0 62 | 63 | 64 | 65 | 66 | Magefox\SSOIntegration\Model\Config\Source\Auth0\Algorithm 67 | 68 | 69 |
70 |
71 |
-------------------------------------------------------------------------------- /etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 0 15 | 0 16 | RS256 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | Magento\Framework\Filesystem\Driver\File 14 | 15 | 16 | 17 | 18 | SSOIntegrationLogger 19 | 20 | Magefox\SSOIntegration\Logger\Handler 21 | 22 | 23 | 24 | 25 | 26 | 27 | Magefox\SSOIntegration\Console\Command\Auth0Sync 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /etc/frontend/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /etc/frontend/events.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /etc/frontend/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Magefox_SSOIntegration::auth0/dashboard/info.phtml 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /view/frontend/requirejs-config.js: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | * @package Magento 2 SSO Integration 3 | * @author http://www.magefox.com 4 | * @copyright (C) 2018- Magefox.Com 5 | * @license MIT 6 | *******************************************************/ 7 | 8 | var config = { 9 | paths: { 10 | 'auth0Lock': 'Magefox_SSOIntegration/js/libs/auth0-lock.min' 11 | }, 12 | shim: { 13 | 'auth0Lock': { 14 | "exports": "auth0Lock" 15 | } 16 | }, 17 | map: { 18 | '*': { 19 | 'magefox.auth0': 'Magefox_SSOIntegration/js/magefox.auth0' 20 | } 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /view/frontend/templates/auth0/dashboard/info.phtml: -------------------------------------------------------------------------------- 1 | 15 |
16 |
escapeHtml(__('Account Information')) ?>
17 |
18 |
19 | 20 | escapeHtml(__('Contact Information')) ?> 21 | 22 |
23 |

24 | escapeHtml($block->getName()) ?>
25 | escapeHtml($block->getCustomer()->getEmail()) ?>
26 |

27 |
28 | 45 |
46 | isNewsletterEnabled()): ?> 47 |
48 | 49 | escapeHtml(__('Newsletters')) ?> 50 | 51 |
52 |

53 | getIsSubscribed()): ?> 54 | escapeHtml(__('You are subscribed to "General Subscription".')) ?> 55 | 56 | escapeHtml(__('You aren\'t subscribed to our newsletter.')) ?> 57 | 58 |

59 | 60 | getChildHtml('customer.account.dashboard.info.extra') ?> 61 |
62 | 65 |
66 | 67 |
68 |
69 | -------------------------------------------------------------------------------- /view/frontend/templates/auth0/link/login.phtml: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /view/frontend/web/js/libs/auth0.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * auth0.min.js v9.3.1 3 | * 4 | * Author: Auth0 5 | * Date: 3/1/2018, 1:08:30 AM 6 | * License: MIT 7 | * 8 | */ 9 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("auth0-js",[],e):"object"==typeof exports?exports["auth0-js"]=e():t.auth0=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){t.exports=n(57)},function(t,e,n){function r(t,e){return e.reduce(function(e,n){return t[n]&&(e[n]=t[n]),e},{})}function i(t,e){var n=[];for(var r in t)e.indexOf(r)===-1&&n.push(r);return n}function o(t){var e=[];for(var n in t)e.push(t[n]);return e}function s(){var t=o(arguments);return t.unshift({}),m.get().apply(void 0,t)}function a(t,e){return{base:e?r(t,e):t,with:function(t,e){return t=e?r(t,e):t,s(this.base,t)}}}function u(t,e){return Object.keys(t).reduce(function(n,r){return e.indexOf(r)===-1&&(n[r]=t[r]),n},{})}function p(t){for(var e,n="",r=0,i=!0,o=!0;r=65&&e<=90||!i&&e>=48&&e<=57?(n+="_",n+=t[r].toLowerCase()):n+=t[r].toLowerCase(),i=e>=48&&e<=57,o=e>=65&&e<=90,r++;return n}function c(t){var e=t.split("_");return e.reduce(function(t,e){return t+e.charAt(0).toUpperCase()+e.slice(1)},e.shift())}function h(t,e){return"object"!=typeof t||y.isArray(t)||null===t?t:(e=e||[],Object.keys(t).reduce(function(n,r){var i=e.indexOf(r)===-1?p(r):r;return n[i]=h(t[r]),n},{}))}function l(t,e){return"object"!=typeof t||y.isArray(t)||null===t?t:(e=e||[],Object.keys(t).reduce(function(n,r){var i=e.indexOf(r)===-1?c(r):r;return n[i]=l(t[r]),n},{}))}function d(t){var e=t.match(/^(https?:)\/\/(([^:\/?#]*)(?::([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);return e&&{href:t,protocol:e[1],host:e[2],hostname:e[3],port:e[4],pathname:e[5],search:e[6],hash:e[7]}}function f(t){if(t){var e=d(t),n=e.protocol+"//"+e.hostname;return e.port&&(n+=":"+e.port),n}}var y=n(4),m=n(14);t.exports={toSnakeCase:h,toCamelCase:l,blacklist:u,merge:a,pick:r,getKeysNotIn:i,extend:s,getOriginFromUrl:f,getLocationFromUrl:d}},function(t,e,n){(function(e){function r(t){e.window.location=t}function i(){return e.window.document}function o(){return e.window}function s(){var t=e.window.location,n=t.origin;return n||(n=a.getOriginFromUrl(t.href)),n}var a=n(1);t.exports={redirect:r,getDocument:i,getWindow:o,getOrigin:s}}).call(e,function(){return this}())},function(t,e,n){var r,i;!function(o,s,a){"undefined"!=typeof t&&t.exports?t.exports=a():(r=a,i="function"==typeof r?r.call(e,n,e,t):r,!(void 0!==i&&(t.exports=i)))}("urljoin",this,function(){function t(t,e){return t=t.replace(/:\//g,"://"),t=t.replace(/([^:\s])\/+/g,"$1/"),t=t.replace(/\/(\?|&|#[^!])/g,"$1"),t=t.replace(/(\?.+)\?/g,"$1&")}return function(){var e=arguments,n={};"object"==typeof arguments[0]&&(e=arguments[0],n=arguments[1]||{});var r=[].slice.call(e,0).join("/");return t(r,n)}})},function(t,e){function n(t,e,n,r){if(n="array"===n?"object":n,t&&typeof t[e]!==n)throw new Error(r)}function r(t,e,n){if(typeof t!==e)throw new Error(n)}function i(t,e,n){if(e.indexOf(t)===-1)throw new Error(n)}function o(t,e,o){if(e.optional&&!t||r(t,e.type,e.message),"object"===e.type&&o)for(var s=Object.keys(o),a=0;a=48&&o<=57||o>=65&&o<=90||o>=97&&o<=122?n+=e.charAt(i):o<128?n+=r[o]:o<2048?n+=r[192|o>>6]+r[128|63&o]:o<55296||o>=57344?n+=r[224|o>>12]+r[128|o>>6&63]+r[128|63&o]:(i+=1,o=65536+((1023&o)<<10|1023&e.charCodeAt(i)),n+=r[240|o>>18]+r[128|o>>12&63]+r[128|o>>6&63]+r[128|63&o])}return n},e.compact=function(t,n){if("object"!=typeof t||null===t)return t;var r=n||[],i=r.indexOf(t);if(i!==-1)return r[i];if(r.push(t),Array.isArray(t)){for(var o=[],s=0;s0&&(t=t.retry(this._timesToRetryFailedRequests)),e.noHeaders)return t;var n=this.headers;t=t.set("Content-Type","application/json");for(var r=Object.keys(this.headers),i=0;i=0&&n.parseArrays&&s<=n.arrayLimit?(r=[],r[s]=a(t,e,n)):r[o]=a(t,e,n)}return r},u=function(t,e,n){if(t){var r=n.allowDots?t.replace(/\.([^.[]+)/g,"[$1]"):t,o=/(\[[^[\]]*])/,s=/(\[[^[\]]*])/g,u=o.exec(r),p=u?r.slice(0,u.index):r,c=[];if(p){if(!n.plainObjects&&i.call(Object.prototype,p)&&!n.allowPrototypes)return;c.push(p)}for(var h=0;null!==(u=s.exec(r))&&h0)throw new Error("Invalid string. Length must be a multiple of 4");return"="===t[e-2]?2:"="===t[e-1]?1:0}function r(t){return 3*t.length/4-n(t)}function i(t){var e,r,i,o,s,a,u=t.length;s=n(t),a=new c(3*u/4-s),i=s>0?u-4:u;var h=0;for(e=0,r=0;e>16&255,a[h++]=o>>8&255,a[h++]=255&o;return 2===s?(o=p[t.charCodeAt(e)]<<2|p[t.charCodeAt(e+1)]>>4,a[h++]=255&o):1===s&&(o=p[t.charCodeAt(e)]<<10|p[t.charCodeAt(e+1)]<<4|p[t.charCodeAt(e+2)]>>2,a[h++]=o>>8&255,a[h++]=255&o),a}function o(t){return u[t>>18&63]+u[t>>12&63]+u[t>>6&63]+u[63&t]}function s(t,e,n){for(var r,i=[],s=e;sc?c:p+a));return 1===r?(e=t[n-1],i+=u[e>>2],i+=u[e<<4&63],i+="=="):2===r&&(e=(t[n-2]<<8)+t[n-1],i+=u[e>>10],i+=u[e>>4&63],i+=u[e<<2&63],i+="="),o.push(i),o.join("")}e.byteLength=r,e.toByteArray=i,e.fromByteArray=a;for(var u=[],p=[],c="undefined"!=typeof Uint8Array?Uint8Array:Array,h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",l=0,d=h.length;l=2&&t._responseTimeoutTimer&&clearTimeout(t._responseTimeoutTimer),4==n){var r;try{r=e.status}catch(t){r=0}if(!r){if(t.timedout||t._aborted)return;return t.crossDomainError()}t.emit("end")}};var r=function(e,n){n.total>0&&(n.percent=n.loaded/n.total*100),n.direction=e,t.emit("progress",n)};if(this.hasListeners("progress"))try{e.onprogress=r.bind(null,"download"),e.upload&&(e.upload.onprogress=r.bind(null,"upload"))}catch(t){}try{this.username&&this.password?e.open(this.method,this.url,!0,this.username,this.password):e.open(this.method,this.url,!0)}catch(t){return this.callback(t)}if(this._withCredentials&&(e.withCredentials=!0),!this._formData&&"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof n&&!this._isHost(n)){var i=this._header["content-type"],o=this._serializer||v.serialize[i?i.split(";")[0]:""];!o&&u(i)&&(o=v.serialize["application/json"]),o&&(n=o(n))}for(var s in this.header)null!=this.header[s]&&this.header.hasOwnProperty(s)&&e.setRequestHeader(s,this.header[s]);return this._responseType&&(e.responseType=this._responseType),this.emit("request",this),e.send("undefined"!=typeof n?n:null),this},v.agent=function(){return new g},["GET","POST","OPTIONS","PATCH","PUT","DELETE"].forEach(function(t){g.prototype[t.toLowerCase()]=function(e,n){var r=new v.Request(t,e);return this._setDefaults(r),n&&r.end(n),r}}),g.prototype.del=g.prototype.delete,v.get=function(t,e,n){var r=v("GET",t);return"function"==typeof e&&(n=e,e=null),e&&r.query(e),n&&r.end(n),r},v.head=function(t,e,n){var r=v("HEAD",t);return"function"==typeof e&&(n=e,e=null),e&&r.query(e),n&&r.end(n),r},v.options=function(t,e,n){var r=v("OPTIONS",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},v.del=h,v.delete=h,v.patch=function(t,e,n){var r=v("PATCH",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},v.post=function(t,e,n){var r=v("POST",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},v.put=function(t,e,n){var r=v("PUT",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r}},function(t,e){"use strict";function n(t){return null!==t&&"object"==typeof t}t.exports=n},function(t,e){var n=function(){function t(t,e,n){t.attachEvent?t.attachEvent("on"+e,n):t.addEventListener&&t.addEventListener(e,n,!1)}function e(t,e,n){t.detachEvent?t.detachEvent("on"+e,n):t.removeEventListener&&t.removeEventListener(e,n,!1)}function n(){if("undefined"==typeof navigator)return!1;var t=-1,e=navigator.userAgent;if("Microsoft Internet Explorer"===navigator.appName){var n=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");null!=n.exec(e)&&(t=parseFloat(RegExp.$1))}else if(e.indexOf("Trident")>-1){var n=new RegExp("rv:([0-9]{2,2}[.0-9]{0,})");null!==n.exec(e)&&(t=parseFloat(RegExp.$1))}return t>=8}function r(){try{var t=navigator.userAgent;return t.indexOf("Fennec/")!=-1||t.indexOf("Firefox/")!=-1&&t.indexOf("Android")!=-1}catch(t){}return!1}function i(){return"undefined"!=typeof window&&window.JSON&&window.JSON.stringify&&window.JSON.parse&&window.postMessage}function o(t){/^https?:\/\//.test(t)||(t=window.location.href);var e=/^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(t);return e?e[1]:t}function s(){for(var t=(window.location,window.opener.frames),e=t.length-1;e>=0;e--)try{if(t[e].location.protocol===window.location.protocol&&t[e].location.host===window.location.host&&t[e].name===a)return t[e]}catch(t){}}var a="__winchan_relay_frame",u="die",p=n();return i()?{open:function(n,i){function s(){if(l&&document.body.removeChild(l),l=void 0,m&&(m=clearInterval(m)),e(window,"message",c),e(window,"unload",s),y)try{y.close()}catch(t){f.postMessage(u,d)}y=f=void 0}function c(t){if(t.origin===d){try{var e=JSON.parse(t.data)}catch(t){if(!i)throw t;i(t)}"ready"===e.a?f.postMessage(g,d):"error"===e.a?(s(),i&&(i(e.d),i=null)):"response"===e.a&&(s(),i&&(i(null,e.d),i=null))}}if(!i)throw"missing required callback argument";var h;n.url||(h="missing required 'url' parameter"),n.relay_url||(h="missing required 'relay_url' parameter"),h&&setTimeout(function(){i(h)},0),n.window_name||(n.window_name=null),n.window_features&&!r()||(n.window_features=void 0);var l,d=n.origin||o(n.url);if(d!==o(n.relay_url))return setTimeout(function(){i("invalid arguments: origin of url and relay_url must match")},0);var f;p&&(l=document.createElement("iframe"),l.setAttribute("src",n.relay_url),l.style.display="none",l.setAttribute("name",a),document.body.appendChild(l),f=l.contentWindow);var y=n.popup||window.open(n.url,n.window_name,n.window_features);n.popup&&(y.location.href=n.url),f||(f=y);var m=setInterval(function(){y&&y.closed&&(s(),i&&(i("User closed the popup window"),i=null))},500),g=JSON.stringify({a:"request",d:n.params});return t(window,"unload",s),t(window,"message",c),{close:s,focus:function(){if(y)try{y.focus()}catch(t){}}}},onOpen:function(n){function r(t){t=JSON.stringify(t),p?c.doPost(t,a):c.postMessage(t,a)}function i(t){var o;try{o=JSON.parse(t.data)}catch(t){}o&&"request"===o.a&&(e(window,"message",i),a=t.origin,n&&setTimeout(function(){n(a,o.d,function(t){n=void 0,r({a:"response",d:t})})},0))}function o(t){if(t.data===u)try{window.close()}catch(t){}}var a="*",c=p?s():window.opener;if(!c)throw"can't find relay frame";t(p?c:window,"message",i),t(p?c:window,"message",o);try{r({a:"ready"})}catch(e){t(c,"load",function(t){r({a:"ready"})})}var h=function(){try{e(p?c:window,"message",o)}catch(t){}n&&r({a:"error",d:"client closed window"}),n=void 0;try{window.close()}catch(t){}};return t(window,"unload",h),{detach:function(){e(window,"unload",h)}}}}:{open:function(t,e,n,r){setTimeout(function(){r("unsupported browser")},0)},onOpen:function(t){setTimeout(function(){t("unsupported browser")},0)}}}();"undefined"!=typeof t&&t.exports&&(t.exports=n)},function(t,e,n){function r(t,e){2===arguments.length?this.auth0=t:e=t,u.check(e,{type:"object",message:"options parameter is not valid"},{domain:{type:"string",message:"domain option is required"},clientID:{type:"string",message:"clientID option is required"},responseType:{optional:!0,type:"string",message:"responseType is not valid"},responseMode:{optional:!0,type:"string",message:"responseMode is not valid"},redirectUri:{optional:!0,type:"string",message:"redirectUri is not valid"},scope:{optional:!0,type:"string",message:"scope is not valid"},audience:{optional:!0,type:"string",message:"audience is not valid"},_disableDeprecationWarnings:{optional:!0,type:"boolean",message:"_disableDeprecationWarnings option is not valid"},_sendTelemetry:{optional:!0,type:"boolean",message:"_sendTelemetry option is not valid"},_telemetryInfo:{optional:!0,type:"object",message:"_telemetryInfo option is not valid"}}),this.baseOptions=e,this.baseOptions._sendTelemetry=this.baseOptions._sendTelemetry!==!1||this.baseOptions._sendTelemetry,this.baseOptions.rootUrl="https://"+this.baseOptions.domain,this.request=new o(this.baseOptions),this.passwordless=new d(this.request,this.baseOptions),this.dbConnection=new f(this.request,this.baseOptions), 10 | this.warn=new l({disableWarnings:!!e._disableDeprecationWarnings})}var i=n(3),o=n(11),s=n(6),a=n(1),u=n(4),p=n(26),c=n(5),h=n(49),l=n(7),d=n(47),f=n(46);r.prototype.buildAuthorizeUrl=function(t){var e,n;return u.check(t,{type:"object",message:"options parameter is not valid"}),e=a.merge(this.baseOptions,["clientID","responseType","responseMode","redirectUri","scope","audience"]).with(t),u.check(e,{type:"object",message:"options parameter is not valid"},{clientID:{type:"string",message:"clientID option is required"},redirectUri:{optional:!0,type:"string",message:"redirectUri option is required"},responseType:{type:"string",message:"responseType option is required"},nonce:{type:"string",message:"nonce option is required",condition:function(t){return t.responseType.indexOf("code")===-1&&t.responseType.indexOf("id_token")!==-1}},scope:{optional:!0,type:"string",message:"scope option is required"},audience:{optional:!0,type:"string",message:"audience option is required"}}),this.baseOptions._sendTelemetry&&(e.auth0Client=this.request.getTelemetryData()),e.connection_scope&&u.isArray(e.connection_scope)&&(e.connection_scope=e.connection_scope.join(",")),e=a.blacklist(e,["username","popupOptions","domain","tenant","timeout"]),e=a.toSnakeCase(e,["auth0Client"]),e=h.oauthAuthorizeParams(this.warn,e),n=s.stringify(e),i(this.baseOptions.rootUrl,"authorize","?"+n)},r.prototype.buildLogoutUrl=function(t){var e,n;return u.check(t,{optional:!0,type:"object",message:"options parameter is not valid"}),e=a.merge(this.baseOptions,["clientID"]).with(t||{}),this.baseOptions._sendTelemetry&&(e.auth0Client=this.request.getTelemetryData()),e=a.toSnakeCase(e,["auth0Client","returnTo"]),n=s.stringify(a.blacklist(e,["federated"])),t&&void 0!==t.federated&&t.federated!==!1&&"false"!==t.federated&&(n+="&federated"),i(this.baseOptions.rootUrl,"v2","logout","?"+n)},r.prototype.loginWithDefaultDirectory=function(t,e){return u.check(t,{type:"object",message:"options parameter is not valid"},{username:{type:"string",message:"username option is required"},password:{type:"string",message:"password option is required"},scope:{optional:!0,type:"string",message:"scope option is required"},audience:{optional:!0,type:"string",message:"audience option is required"}}),t.grantType="password",this.oauthToken(t,e)},r.prototype.login=function(t,e){return u.check(t,{type:"object",message:"options parameter is not valid"},{username:{type:"string",message:"username option is required"},password:{type:"string",message:"password option is required"},realm:{type:"string",message:"realm option is required"},scope:{optional:!0,type:"string",message:"scope option is required"},audience:{optional:!0,type:"string",message:"audience option is required"}}),t.grantType="http://auth0.com/oauth/grant-type/password-realm",this.oauthToken(t,e)},r.prototype.oauthToken=function(t,e){var n,r;return u.check(t,{type:"object",message:"options parameter is not valid"}),u.check(e,{type:"function",message:"cb parameter is not valid"}),n=i(this.baseOptions.rootUrl,"oauth","token"),r=a.merge(this.baseOptions,["clientID","scope","audience"]).with(t),u.check(r,{type:"object",message:"options parameter is not valid"},{clientID:{type:"string",message:"clientID option is required"},grantType:{type:"string",message:"grantType option is required"},scope:{optional:!0,type:"string",message:"scope option is required"},audience:{optional:!0,type:"string",message:"audience option is required"}}),r=a.toSnakeCase(r,["auth0Client"]),r=h.oauthTokenParams(this.warn,r),this.request.post(n).send(r).end(c(e))},r.prototype.loginWithResourceOwner=function(t,e){var n,r;return u.check(t,{type:"object",message:"options parameter is not valid"},{username:{type:"string",message:"username option is required"},password:{type:"string",message:"password option is required"},connection:{type:"string",message:"connection option is required"},scope:{optional:!0,type:"string",message:"scope option is required"}}),u.check(e,{type:"function",message:"cb parameter is not valid"}),n=i(this.baseOptions.rootUrl,"oauth","ro"),r=a.merge(this.baseOptions,["clientID","scope"]).with(t,["username","password","scope","connection","device"]),r=a.toSnakeCase(r,["auth0Client"]),r.grant_type=r.grant_type||"password",this.request.post(n).send(r).end(c(e))},r.prototype.getSSOData=function(t,e){if(!this.auth0){var r=n(28);this.auth0=new r(this.baseOptions)}"function"==typeof t&&(e=t),u.check(e,{type:"function",message:"cb parameter is not valid"});var i=this.baseOptions.clientID,o=p.get()||{};this.auth0.checkSession({responseType:"token id_token",scope:"openid profile email",connection:o.lastUsedConnection,timeout:5e3},function(t,n){return t?"login_required"===t.error?e(null,{sso:!1}):("consent_required"===t.error&&(t.error_description="Consent required. When using `getSSOData`, the user has to be authenticated with the following scope: `openid profile email`."),e(t,{sso:!1})):o.lastUsedSub&&o.lastUsedSub!==n.idTokenPayload.sub?e(t,{sso:!1}):e(null,{lastUsedConnection:{name:o.lastUsedConnection},lastUsedUserID:n.idTokenPayload.sub,lastUsedUsername:n.idTokenPayload.email||n.idTokenPayload.name,lastUsedClientID:i,sessionClients:[i],sso:!0})})},r.prototype.userInfo=function(t,e){var n;return u.check(t,{type:"string",message:"accessToken parameter is not valid"}),u.check(e,{type:"function",message:"cb parameter is not valid"}),n=i(this.baseOptions.rootUrl,"userinfo"),this.request.get(n).set("Authorization","Bearer "+t).end(c(e,{ignoreCasing:!0}))},r.prototype.delegation=function(t,e){var n,r;return u.check(t,{type:"object",message:"options parameter is not valid"},{grant_type:{type:"string",message:"grant_type option is required"}}),u.check(e,{type:"function",message:"cb parameter is not valid"}),n=i(this.baseOptions.rootUrl,"delegation"),r=a.merge(this.baseOptions,["clientID"]).with(t),r=a.toSnakeCase(r,["auth0Client"]),this.request.post(n).send(r).end(c(e))},r.prototype.getUserCountry=function(t){var e;return u.check(t,{type:"function",message:"cb parameter is not valid"}),e=i(this.baseOptions.rootUrl,"user","geoloc","country"),this.request.get(e).end(c(t))},t.exports=r},function(t,e,n){function r(t){var e=t.length%4,n=4-e;return 0===e?t:t+new Array(1+n).join("=")}function i(t){for(var e=new Array(t.length),n=0;n>>2]>>>24-o%4*8&255;e[r+o>>>2]|=s<<24-(r+o)%4*8}else for(var o=0;o>>2]=n[o>>>2];return this.sigBytes+=i,this},clamp:function(){var e=this.words,n=this.sigBytes;e[n>>>2]&=4294967295<<32-n%4*8,e.length=t.ceil(n/4)},clone:function(){var t=o.clone.call(this);return t.words=this.words.slice(0),t},random:function(e){for(var n,r=[],i=function(e){var e=e,n=987654321,r=4294967295;return function(){n=36969*(65535&n)+(n>>16)&r,e=18e3*(65535&e)+(e>>16)&r;var i=(n<<16)+e&r;return i/=4294967296,i+=.5,i*(t.random()>.5?1:-1)}},o=0;o>>2]>>>24-i%4*8&255;r.push((o>>>4).toString(16)),r.push((15&o).toString(16))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;r>>3]|=parseInt(t.substr(r,2),16)<<24-r%8*4;return new s.init(n,e/2)}},p=a.Latin1={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],i=0;i>>2]>>>24-i%4*8&255;r.push(String.fromCharCode(o))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;r>>2]|=(255&t.charCodeAt(r))<<24-r%4*8;return new s.init(n,e)}},c=a.Utf8={stringify:function(t){try{return decodeURIComponent(escape(p.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return p.parse(unescape(encodeURIComponent(t)))}},h=i.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new s.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=c.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(e){var n=this._data,r=n.words,i=n.sigBytes,o=this.blockSize,a=4*o,u=i/a;u=e?t.ceil(u):t.max((0|u)-this._minBufferSize,0);var p=u*o,c=t.min(4*p,i);if(p){for(var h=0;h>>7)^(f<<14|f>>>18)^f>>>3,m=p[d-2],g=(m<<15|m>>>17)^(m<<13|m>>>19)^m>>>10;p[d]=y+p[d-7]+g+p[d-16]}var v=a&c^~a&h,b=r&i^r&o^i&o,w=(r<<30|r>>>2)^(r<<19|r>>>13)^(r<<10|r>>>22),_=(a<<26|a>>>6)^(a<<21|a>>>11)^(a<<7|a>>>25),T=l+_+v+u[d]+p[d],O=w+b;l=h,h=c,c=a,a=s+T|0,s=o,o=i,i=r,r=T+O|0}n[0]=n[0]+r|0,n[1]=n[1]+i|0,n[2]=n[2]+o|0,n[3]=n[3]+s|0,n[4]=n[4]+a|0,n[5]=n[5]+c|0,n[6]=n[6]+h|0,n[7]=n[7]+l|0},_doFinalize:function(){var t=this._data,n=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;return n[i>>>5]|=128<<24-i%32,n[(i+64>>>9<<4)+14]=e.floor(r/4294967296),n[(i+64>>>9<<4)+15]=r,t.sigBytes=4*n.length,this._process(),this._hash},clone:function(){var t=o.clone.call(this);return t._hash=this._hash.clone(),t}});n.SHA256=o._createHelper(c),n.HmacSHA256=o._createHmacHelper(c)}(Math),t.SHA256})},function(t,e){function n(){}n.prototype.get=function(){return null},n.prototype.has=function(){return!1},n.prototype.set=function(){},t.exports=n},function(t,e){function n(t){this.name="ConfigurationError",this.message=t||""}function r(t){this.name="TokenValidationError",this.message=t||""}n.prototype=Error.prototype,r.prototype=Error.prototype,t.exports={ConfigurationError:n,TokenValidationError:r}},function(t,e,n){function r(t){var e=s.decodeToHEX(t.n),n=s.decodeToHEX(t.e);return{modulus:e,exp:n}}function i(t,e){var n=o(t.iss,".well-known","jwks.json");return a.get(n).end(function(n,i){var o,s,a=null;for(n&&e(n),o=0;o0&&e.length>0))throw new Error("Invalid key data");this.n=new o(t,16),this.e=parseInt(e,16)}function i(t){for(var e in a){var n=a[e],r=n.length;if(t.substring(0,r)===n)return{alg:e,hash:t.substring(r)}}return[]}var o=n(38).BigInteger,s=n(32),a={sha1:"3021300906052b0e03021a05000414",sha224:"302d300d06096086480165030402040500041c",sha256:"3031300d060960864801650304020105000420",sha384:"3041300d060960864801650304020205000430",sha512:"3051300d060960864801650304020305000440",md2:"3020300c06082a864886f70d020205000410",md5:"3020300c06082a864886f70d020505000410",ripemd160:"3021300906052b2403020105000414"},u={sha256:s};r.prototype.verify=function(t,e){e=e.replace(/[^0-9a-f]|[\s\n]]/gi,"");var n=new o(e,16);if(n.bitLength()>this.n.bitLength())throw new Error("Signature does not match with the key modulus.");var r=n.modPowInt(this.e,this.n),s=r.toString(16).replace(/^1f+00/,""),a=i(s);if(0===a.length)return!1;if(!u.hasOwnProperty(a.alg))throw new Error("Hashing algorithm is not supported.");var p=u[a.alg](t).toString();return a.hash===p},t.exports=r},function(t,e,n){function r(t){var e=t||{};if(this.jwksCache=e.jwksCache||new u,this.expectedAlg=e.expectedAlg||"RS256",this.issuer=e.issuer,this.audience=e.audience,this.leeway=e.leeway||0,this.__disableExpirationCheck=e.__disableExpirationCheck||!1,this.leeway<0||this.leeway>60)throw new a.ConfigurationError("The leeway should be positive and lower than a minute.");if(p.indexOf(this.expectedAlg)===-1)throw new a.ConfigurationError("Algorithm "+this.expectedAlg+" is not supported. (Expected algs: ["+p.join(",")+"])")}var i=n(36),o=n(18),s=n(35),a=n(34),u=n(33),p=["RS256"];r.prototype.verify=function(t,e,n){var r=this.decode(t);if(r instanceof Error)return n(r,!1);var i=r.encoded.header+"."+r.encoded.payload,s=o.decodeToHEX(r.encoded.signature),u=r.header.alg,c=r.header.kid,h=r.payload.aud,l=r.payload.iss,d=r.payload.exp,f=r.payload.nbf,y=r.payload.nonce||null;if(this.issuer!==l)return n(new a.TokenValidationError("Issuer "+l+" is not valid."),!1);if(this.audience!==h)return n(new a.TokenValidationError("Audience "+h+" is not valid."),!1);if(this.expectedAlg!==u)return n(new a.TokenValidationError("Algorithm "+u+" is not supported. (Expected algs: ["+p.join(",")+"])"),!1);if(y!==e)return n(new a.TokenValidationError("Nonce does not match."),!1);var m=this.verifyExpAndNbf(d,f);return m?n(m,!1):this.getRsaVerifier(l,c,function(t,e){return t?n(t):e.verify(i,s)?n(null,r.payload):n(new a.TokenValidationError("Invalid signature."))})},r.prototype.verifyExpAndNbf=function(t,e){var n=new Date,r=new Date(0),i=new Date(0);return this.__disableExpirationCheck?null:(r.setUTCSeconds(t+this.leeway),n>r?new a.TokenValidationError("Expired token."):"undefined"==typeof e?null:(i.setUTCSeconds(e-this.leeway),nr?new a.TokenValidationError("Expired token."):(i.setUTCSeconds(e-this.leeway),n=0;){var s=e*this[t++]+n[r]+i;i=Math.floor(s/67108864),n[r++]=67108863&s}return i}function o(t,e,n,r,i,o){for(var s=32767&e,a=e>>15;--o>=0;){var u=32767&this[t],p=this[t++]>>15,c=a*u+p*s;u=s*u+((32767&c)<<15)+n[r]+(1073741823&i),i=(u>>>30)+(c>>>15)+a*p+(i>>>30),n[r++]=1073741823&u}return i}function s(t,e,n,r,i,o){for(var s=16383&e,a=e>>14;--o>=0;){var u=16383&this[t],p=this[t++]>>14,c=a*u+p*s;u=s*u+((16383&c)<<14)+n[r]+i,i=(u>>28)+(c>>14)+a*p,n[r++]=268435455&u}return i}function a(t){return me.charAt(t)}function u(t,e){var n=ge[t.charCodeAt(e)];return null==n?-1:n}function p(t){for(var e=this.t-1;e>=0;--e)t[e]=this[e];t.t=this.t,t.s=this.s}function c(t){this.t=1,this.s=t<0?-1:0,t>0?this[0]=t:t<-1?this[0]=t+this.DV:this.t=0}function h(t){var e=r();return e.fromInt(t),e}function l(t,e){var r;if(16==e)r=4;else if(8==e)r=3;else if(256==e)r=8;else if(2==e)r=1;else if(32==e)r=5;else{if(4!=e)return void this.fromRadix(t,e);r=2}this.t=0,this.s=0;for(var i=t.length,o=!1,s=0;--i>=0;){var a=8==r?255&t[i]:u(t,i);a<0?"-"==t.charAt(i)&&(o=!0):(o=!1,0==s?this[this.t++]=a:s+r>this.DB?(this[this.t-1]|=(a&(1<>this.DB-s):this[this.t-1]|=a<=this.DB&&(s-=this.DB))}8==r&&0!=(128&t[0])&&(this.s=-1,s>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==t;)--this.t}function f(t){if(this.s<0)return"-"+this.negate().toString(t);var e;if(16==t)e=4;else if(8==t)e=3;else if(2==t)e=1;else if(32==t)e=5;else{if(4!=t)return this.toRadix(t);e=2}var n,r=(1<0)for(u>u)>0&&(i=!0,o=a(n));s>=0;)u>(u+=this.DB-e)):(n=this[s]>>(u-=e)&r,u<=0&&(u+=this.DB,--s)),n>0&&(i=!0),i&&(o+=a(n));return i?o:"0"}function y(){var t=r();return n.ZERO.subTo(this,t),t}function m(){return this.s<0?this.negate():this}function g(t){var e=this.s-t.s;if(0!=e)return e;var n=this.t;if(e=n-t.t,0!=e)return this.s<0?-e:e;for(;--n>=0;)if(0!=(e=this[n]-t[n]))return e;return 0}function v(t){var e,n=1;return 0!=(e=t>>>16)&&(t=e,n+=16),0!=(e=t>>8)&&(t=e,n+=8),0!=(e=t>>4)&&(t=e,n+=4),0!=(e=t>>2)&&(t=e,n+=2),0!=(e=t>>1)&&(t=e,n+=1),n}function b(){return this.t<=0?0:this.DB*(this.t-1)+v(this[this.t-1]^this.s&this.DM)}function w(t,e){var n;for(n=this.t-1;n>=0;--n)e[n+t]=this[n]; 11 | for(n=t-1;n>=0;--n)e[n]=0;e.t=this.t+t,e.s=this.s}function _(t,e){for(var n=t;n=0;--n)e[n+s+1]=this[n]>>i|a,a=(this[n]&o)<=0;--n)e[n]=0;e[s]=a,e.t=this.t+s+1,e.s=this.s,e.clamp()}function O(t,e){e.s=this.s;var n=Math.floor(t/this.DB);if(n>=this.t)return void(e.t=0);var r=t%this.DB,i=this.DB-r,o=(1<>r;for(var s=n+1;s>r;r>0&&(e[this.t-n-1]|=(this.s&o)<>=this.DB;if(t.t>=this.DB;r+=this.s}else{for(r+=this.s;n>=this.DB;r-=t.s}e.s=r<0?-1:0,r<-1?e[n++]=this.DV+r:r>0&&(e[n++]=r),e.t=n,e.clamp()}function x(t,e){var r=this.abs(),i=t.abs(),o=r.t;for(e.t=o+i.t;--o>=0;)e[o]=0;for(o=0;o=0;)t[n]=0;for(n=0;n=e.DV&&(t[n+e.t]-=e.DV,t[n+e.t+1]=1)}t.t>0&&(t[t.t-1]+=e.am(n,e[n],t,2*n,0,1)),t.s=0,t.clamp()}function D(t,e,i){var o=t.abs();if(!(o.t<=0)){var s=this.abs();if(s.t0?(o.lShiftTo(c,a),s.lShiftTo(c,i)):(o.copyTo(a),s.copyTo(i));var h=a.t,l=a[h-1];if(0!=l){var d=l*(1<1?a[h-2]>>this.F2:0),f=this.FV/d,y=(1<=0&&(i[i.t++]=1,i.subTo(w,i)),n.ONE.dlShiftTo(h,w),w.subTo(a,a);a.t=0;){var _=i[--g]==l?this.DM:Math.floor(i[g]*f+(i[g-1]+m)*y);if((i[g]+=a.am(0,_,i,b,0,h))<_)for(a.dlShiftTo(b,w),i.subTo(w,i);i[g]<--_;)i.subTo(w,i)}null!=e&&(i.drShiftTo(h,e),u!=p&&n.ZERO.subTo(e,e)),i.t=h,i.clamp(),c>0&&i.rShiftTo(c,i),u<0&&n.ZERO.subTo(i,i)}}}function A(t){var e=r();return this.abs().divRemTo(t,null,e),this.s<0&&e.compareTo(n.ZERO)>0&&t.subTo(e,e),e}function S(t){this.m=t}function E(t){return t.s<0||t.compareTo(this.m)>=0?t.mod(this.m):t}function q(t){return t}function j(t){t.divRemTo(this.m,null,t)}function I(t,e,n){t.multiplyTo(e,n),this.reduce(n)}function R(t,e){t.squareTo(e),this.reduce(e)}function M(){if(this.t<1)return 0;var t=this[0];if(0==(1&t))return 0;var e=3&t;return e=e*(2-(15&t)*e)&15,e=e*(2-(255&t)*e)&255,e=e*(2-((65535&t)*e&65535))&65535,e=e*(2-t*e%this.DV)%this.DV,e>0?this.DV-e:-e}function U(t){this.m=t,this.mp=t.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(e,e),e}function P(t){var e=r();return t.copyTo(e),this.reduce(e),e}function L(t){for(;t.t<=this.mt2;)t[t.t++]=0;for(var e=0;e>15)*this.mpl&this.um)<<15)&t.DM;for(n=e+this.m.t,t[n]+=this.m.am(0,r,t,e,0,this.m.t);t[n]>=t.DV;)t[n]-=t.DV,t[++n]++}t.clamp(),t.drShiftTo(this.m.t,t),t.compareTo(this.m)>=0&&t.subTo(this.m,t)}function H(t,e){t.squareTo(e),this.reduce(e)}function N(t,e,n){t.multiplyTo(e,n),this.reduce(n)}function V(){return 0==(this.t>0?1&this[0]:this.s)}function W(t,e){if(t>4294967295||t<1)return n.ONE;var i=r(),o=r(),s=e.convert(this),a=v(t)-1;for(s.copyTo(i);--a>=0;)if(e.sqrTo(i,o),(t&1<0)e.mulTo(o,s,i);else{var u=i;i=o,o=u}return e.revert(i)}function z(t,e){var n;return n=t<256||e.isEven()?new S(e):new U(e),this.exp(t,n)}function F(){var t=r();return this.copyTo(t),t}function J(){if(this.s<0){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<>24}function $(){return 0==this.t?this.s:this[0]<<16>>16}function Z(t){return Math.floor(Math.LN2*this.DB/Math.log(t))}function K(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1}function G(t){if(null==t&&(t=10),0==this.signum()||t<2||t>36)return"0";var e=this.chunkSize(t),n=Math.pow(t,e),i=h(n),o=r(),s=r(),a="";for(this.divRemTo(i,o,s);o.signum()>0;)a=(n+s.intValue()).toString(t).substr(1)+a,o.divRemTo(i,o,s);return s.intValue().toString(t)+a}function Q(t,e){this.fromInt(0),null==e&&(e=10);for(var r=this.chunkSize(e),i=Math.pow(e,r),o=!1,s=0,a=0,p=0;p=r&&(this.dMultiply(i),this.dAddOffset(a,0),s=0,a=0))}s>0&&(this.dMultiply(Math.pow(e,s)),this.dAddOffset(a,0)),o&&n.ZERO.subTo(this,this)}function Y(t,e,r){if("number"==typeof e)if(t<2)this.fromInt(1);else for(this.fromNumber(t,r),this.testBit(t-1)||this.bitwiseTo(n.ONE.shiftLeft(t-1),at,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(e);)this.dAddOffset(2,0),this.bitLength()>t&&this.subTo(n.ONE.shiftLeft(t-1),this);else{var i=new Array,o=7&t;i.length=(t>>3)+1,e.nextBytes(i),o>0?i[0]&=(1<0)for(r>r)!=(this.s&this.DM)>>r&&(e[i++]=n|this.s<=0;)r<8?(n=(this[t]&(1<>(r+=this.DB-8)):(n=this[t]>>(r-=8)&255,r<=0&&(r+=this.DB,--t)),0!=(128&n)&&(n|=-256),0==i&&(128&this.s)!=(128&n)&&++i,(i>0||n!=this.s)&&(e[i++]=n);return e}function et(t){return 0==this.compareTo(t)}function nt(t){return this.compareTo(t)<0?this:t}function rt(t){return this.compareTo(t)>0?this:t}function it(t,e,n){var r,i,o=Math.min(t.t,this.t);for(r=0;r>=16,e+=16),0==(255&t)&&(t>>=8,e+=8),0==(15&t)&&(t>>=4,e+=4),0==(3&t)&&(t>>=2,e+=2),0==(1&t)&&++e,e}function gt(){for(var t=0;t=this.t?0!=this.s:0!=(this[e]&1<>=this.DB;if(t.t>=this.DB;r+=this.s}else{for(r+=this.s;n>=this.DB;r+=t.s}e.s=r<0?-1:0,r>0?e[n++]=r:r<-1&&(e[n++]=this.DV+r),e.t=n,e.clamp()}function Ct(t){var e=r();return this.addTo(t,e),e}function Dt(t){var e=r();return this.subTo(t,e),e}function At(t){var e=r();return this.multiplyTo(t,e),e}function St(){var t=r();return this.squareTo(t),t}function Et(t){var e=r();return this.divRemTo(t,e,null),e}function qt(t){var e=r();return this.divRemTo(t,null,e),e}function jt(t){var e=r(),n=r();return this.divRemTo(t,e,n),new Array(e,n)}function It(t){this[this.t]=this.am(0,t-1,this,0,0,this.t),++this.t,this.clamp()}function Rt(t,e){if(0!=t){for(;this.t<=e;)this[this.t++]=0;for(this[e]+=t;this[e]>=this.DV;)this[e]-=this.DV,++e>=this.t&&(this[this.t++]=0),++this[e]}}function Mt(){}function Ut(t){return t}function Bt(t,e,n){t.multiplyTo(e,n)}function Pt(t,e){t.squareTo(e)}function Lt(t){return this.exp(t,new Mt)}function Ht(t,e,n){var r=Math.min(this.t+t.t,e);for(n.s=0,n.t=r;r>0;)n[--r]=0;var i;for(i=n.t-this.t;r=0;)n[r]=0;for(r=Math.max(e-this.t,0);r2*this.m.t)return t.mod(this.m);if(t.compareTo(this.m)<0)return t;var e=r();return t.copyTo(e),this.reduce(e),e}function zt(t){return t}function Ft(t){for(t.drShiftTo(this.m.t-1,this.r2),t.t>this.m.t+1&&(t.t=this.m.t+1,t.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);t.compareTo(this.r2)<0;)t.dAddOffset(1,this.m.t+1);for(t.subTo(this.r2,t);t.compareTo(this.m)>=0;)t.subTo(this.m,t)}function Jt(t,e){t.squareTo(e),this.reduce(e)}function Xt(t,e,n){t.multiplyTo(e,n),this.reduce(n)}function $t(t,e){var n,i,o=t.bitLength(),s=h(1);if(o<=0)return s;n=o<18?1:o<48?3:o<144?4:o<768?5:6,i=o<8?new S(e):e.isEven()?new Vt(e):new U(e);var a=new Array,u=3,p=n-1,c=(1<1){var l=r();for(i.sqrTo(a[1],l);u<=c;)a[u]=r(),i.mulTo(l,a[u-2],a[u]),u+=2}var d,f,y=t.t-1,m=!0,g=r();for(o=v(t[y])-1;y>=0;){for(o>=p?d=t[y]>>o-p&c:(d=(t[y]&(1<0&&(d|=t[y-1]>>this.DB+o-p)),u=n;0==(1&d);)d>>=1,--u;if((o-=u)<0&&(o+=this.DB,--y),m)a[d].copyTo(s),m=!1;else{for(;u>1;)i.sqrTo(s,g),i.sqrTo(g,s),u-=2;u>0?i.sqrTo(s,g):(f=s,s=g,g=f),i.mulTo(g,a[d],s)}for(;y>=0&&0==(t[y]&1<0&&(e.rShiftTo(o,e),n.rShiftTo(o,n));e.signum()>0;)(i=e.getLowestSetBit())>0&&e.rShiftTo(i,e),(i=n.getLowestSetBit())>0&&n.rShiftTo(i,n),e.compareTo(n)>=0?(e.subTo(n,e),e.rShiftTo(1,e)):(n.subTo(e,n),n.rShiftTo(1,n));return o>0&&n.lShiftTo(o,n),n}function Kt(t){if(t<=0)return 0;var e=this.DV%t,n=this.s<0?t-1:0;if(this.t>0)if(0==e)n=this[0]%t;else for(var r=this.t-1;r>=0;--r)n=(e*n+this[r])%t;return n}function Gt(t){var e=t.isEven();if(this.isEven()&&e||0==t.signum())return n.ZERO;for(var r=t.clone(),i=this.clone(),o=h(1),s=h(0),a=h(0),u=h(1);0!=r.signum();){for(;r.isEven();)r.rShiftTo(1,r),e?(o.isEven()&&s.isEven()||(o.addTo(this,o),s.subTo(t,s)),o.rShiftTo(1,o)):s.isEven()||s.subTo(t,s),s.rShiftTo(1,s);for(;i.isEven();)i.rShiftTo(1,i),e?(a.isEven()&&u.isEven()||(a.addTo(this,a),u.subTo(t,u)),a.rShiftTo(1,a)):u.isEven()||u.subTo(t,u),u.rShiftTo(1,u);r.compareTo(i)>=0?(r.subTo(i,r),e&&o.subTo(a,o),s.subTo(u,s)):(i.subTo(r,i),e&&a.subTo(o,a),u.subTo(s,u))}return 0!=i.compareTo(n.ONE)?n.ZERO:u.compareTo(t)>=0?u.subtract(t):u.signum()<0?(u.addTo(t,u),u.signum()<0?u.add(t):u):u}function Qt(t){var e,n=this.abs();if(1==n.t&&n[0]<=ve[ve.length-1]){for(e=0;e>1,t>ve.length&&(t=ve.length);for(var s=r(),a=0;a>8&255,_e[Te++]^=t>>16&255,_e[Te++]^=t>>24&255,Te>=Ce&&(Te-=Ce)}function ee(){te((new Date).getTime())}function ne(){if(null==we){for(ee(),we=ue(),we.init(_e),Te=0;Te<_e.length;++Te)_e[Te]=0;Te=0}return we.next()}function re(t){var e;for(e=0;e>>8,_e[Te++]=255&Oe;Te=0,ee()}ie.prototype.nextBytes=re,oe.prototype.init=se,oe.prototype.next=ae;var Ce=256;n.SecureRandom=ie,n.BigInteger=n,e=t.exports=n}).call(this)},function(t,e){function n(){this._defaults=[]}["use","on","once","set","query","type","accept","auth","withCredentials","sortQuery","retry","ok","redirects","timeout","buffer","serialize","parse","ca","key","pfx","cert"].forEach(function(t){n.prototype[t]=function(){return this._defaults.push({fn:t,arguments:arguments}),this}}),n.prototype._setDefaults=function(t){this._defaults.forEach(function(e){t[e.fn].apply(t,e.arguments)})},t.exports=n},function(t,e,n){"use strict";function r(t){if(t)return i(t)}function i(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}var o=n(20);t.exports=r,r.prototype.clearTimeout=function(){return clearTimeout(this._timer),clearTimeout(this._responseTimeoutTimer),delete this._timer,delete this._responseTimeoutTimer,this},r.prototype.parse=function(t){return this._parser=t,this},r.prototype.responseType=function(t){return this._responseType=t,this},r.prototype.serialize=function(t){return this._serializer=t,this},r.prototype.timeout=function(t){if(!t||"object"!=typeof t)return this._timeout=t,this._responseTimeout=0,this;for(var e in t)switch(e){case"deadline":this._timeout=t.deadline;break;case"response":this._responseTimeout=t.response;break;default:console.warn("Unknown timeout option",e)}return this},r.prototype.retry=function(t,e){return 0!==arguments.length&&t!==!0||(t=1),t<=0&&(t=0),this._maxRetries=t,this._retries=0,this._retryCallback=e,this};var s=["ECONNRESET","ETIMEDOUT","EADDRINFO","ESOCKETTIMEDOUT"];r.prototype._shouldRetry=function(t,e){if(!this._maxRetries||this._retries++>=this._maxRetries)return!1;if(this._retryCallback)try{var n=this._retryCallback(t,e);if(n===!0)return!0;if(n===!1)return!1}catch(t){console.error(t)}if(e&&e.status&&e.status>=500&&501!=e.status)return!0;if(t){if(t.code&&~s.indexOf(t.code))return!0;if(t.timeout&&"ECONNABORTED"==t.code)return!0;if(t.crossDomain)return!0}return!1},r.prototype._retry=function(){return this.clearTimeout(),this.req&&(this.req=null,this.req=this.request()),this._aborted=!1,this.timedout=!1,this._end()},r.prototype.then=function(t,e){if(!this._fullfilledPromise){var n=this;this._endCalled&&console.warn("Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises"),this._fullfilledPromise=new Promise(function(t,e){n.end(function(n,r){n?e(n):t(r)})})}return this._fullfilledPromise.then(t,e)},r.prototype.catch=function(t){return this.then(void 0,t)},r.prototype.use=function(t){return t(this),this},r.prototype.ok=function(t){if("function"!=typeof t)throw Error("Callback required");return this._okCallback=t,this},r.prototype._isResponseOK=function(t){return!!t&&(this._okCallback?this._okCallback(t):t.status>=200&&t.status<300)},r.prototype.get=function(t){return this._header[t.toLowerCase()]},r.prototype.getHeader=r.prototype.get,r.prototype.set=function(t,e){if(o(t)){for(var n in t)this.set(n,t[n]);return this}return this._header[t.toLowerCase()]=e,this.header[t]=e,this},r.prototype.unset=function(t){return delete this._header[t.toLowerCase()],delete this.header[t],this},r.prototype.field=function(t,e){if(null===t||void 0===t)throw new Error(".field(name, val) name can not be empty");if(this._data&&console.error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()"),o(t)){for(var n in t)this.field(n,t[n]);return this}if(Array.isArray(e)){for(var r in e)this.field(t,e[r]);return this}if(null===e||void 0===e)throw new Error(".field(name, val) val can not be empty");return"boolean"==typeof e&&(e=""+e),this._getFormData().append(t,e),this},r.prototype.abort=function(){return this._aborted?this:(this._aborted=!0,this.xhr&&this.xhr.abort(),this.req&&this.req.abort(),this.clearTimeout(),this.emit("abort"),this)},r.prototype._auth=function(t,e,n,r){switch(n.type){case"basic":this.set("Authorization","Basic "+r(t+":"+e));break;case"auto":this.username=t,this.password=e;break;case"bearer":this.set("Authorization","Bearer "+t)}return this},r.prototype.withCredentials=function(t){return void 0==t&&(t=!0),this._withCredentials=t,this},r.prototype.redirects=function(t){return this._maxRedirects=t,this},r.prototype.maxResponseSize=function(t){if("number"!=typeof t)throw TypeError("Invalid argument");return this._maxResponseSize=t,this},r.prototype.toJSON=function(){return{method:this.method,url:this.url,data:this._data,headers:this._header}},r.prototype.send=function(t){var e=o(t),n=this._header["content-type"];if(this._formData&&console.error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()"),e&&!this._data)Array.isArray(t)?this._data=[]:this._isHost(t)||(this._data={});else if(t&&this._data&&this._isHost(this._data))throw Error("Can't merge these send calls");if(e&&o(this._data))for(var r in t)this._data[r]=t[r];else"string"==typeof t?(n||this.type("form"),n=this._header["content-type"],"application/x-www-form-urlencoded"==n?this._data=this._data?this._data+"&"+t:t:this._data=(this._data||"")+t):this._data=t;return!e||this._isHost(t)?this:(n||this.type("json"),this)},r.prototype.sortQuery=function(t){return this._sort="undefined"==typeof t||t,this},r.prototype._finalizeQueryString=function(){var t=this._query.join("&");if(t&&(this.url+=(this.url.indexOf("?")>=0?"&":"?")+t),this._query.length=0,this._sort){var e=this.url.indexOf("?");if(e>=0){var n=this.url.substring(e+1).split("&");"function"==typeof this._sort?n.sort(this._sort):n.sort(),this.url=this.url.substring(0,e)+"?"+n.join("&")}}},r.prototype._appendQueryString=function(){console.trace("Unsupported")},r.prototype._timeoutError=function(t,e,n){if(!this._aborted){var r=new Error(t+e+"ms exceeded");r.timeout=e,r.code="ECONNABORTED",r.errno=n,this.timedout=!0,this.abort(),this.callback(r)}},r.prototype._setTimeouts=function(){var t=this;this._timeout&&!this._timer&&(this._timer=setTimeout(function(){t._timeoutError("Timeout of ",t._timeout,"ETIME")},this._timeout)),this._responseTimeout&&!this._responseTimeoutTimer&&(this._responseTimeoutTimer=setTimeout(function(){t._timeoutError("Response timeout of ",t._responseTimeout,"ETIMEDOUT")},this._responseTimeout))}},function(t,e,n){"use strict";function r(t){if(t)return i(t)}function i(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}var o=n(42);t.exports=r,r.prototype.get=function(t){return this.header[t.toLowerCase()]},r.prototype._setHeaderProperties=function(t){var e=t["content-type"]||"";this.type=o.type(e);var n=o.params(e);for(var r in n)this[r]=n[r];this.links={};try{t.link&&(this.links=o.parseLinks(t.link))}catch(t){}},r.prototype._setStatusProperties=function(t){var e=t/100|0;this.status=this.statusCode=t,this.statusType=e,this.info=1==e,this.ok=2==e,this.redirect=3==e,this.clientError=4==e,this.serverError=5==e,this.error=(4==e||5==e)&&this.toError(),this.accepted=202==t,this.noContent=204==t,this.badRequest=400==t,this.unauthorized=401==t,this.notAcceptable=406==t,this.forbidden=403==t,this.notFound=404==t}},function(t,e){"use strict";e.type=function(t){return t.split(/ *; */).shift()},e.params=function(t){return t.split(/ *; */).reduce(function(t,e){var n=e.split(/ *= */),r=n.shift(),i=n.shift();return r&&i&&(t[r]=i),t},{})},e.parseLinks=function(t){return t.split(/ *, */).reduce(function(t,e){var n=e.split(/ *; */),r=n[0].slice(1,-1),i=n[1].split(/ *= */)[1].slice(1,-1);return t[i]=r,t},{})},e.cleanHeader=function(t,e){return delete t["content-type"],delete t["content-length"],delete t["transfer-encoding"],delete t.host,e&&(delete t.authorization,delete t.cookie),t}},,,,function(t,e,n){function r(t,e){this.baseOptions=e,this.request=t}var i=n(3),o=n(1),s=n(4),a=n(5);r.prototype.signup=function(t,e){var n,r,u;return s.check(t,{type:"object",message:"options parameter is not valid"},{connection:{type:"string",message:"connection option is required"},email:{type:"string",message:"email option is required"},password:{type:"string",message:"password option is required"}}),s.check(e,{type:"function",message:"cb parameter is not valid"}),n=i(this.baseOptions.rootUrl,"dbconnections","signup"),r=o.merge(this.baseOptions,["clientID"]).with(t),u=r.user_metadata||r.userMetadata,r=o.blacklist(r,["scope","userMetadata","user_metadata"]),r=o.toSnakeCase(r,["auth0Client"]),u&&(r.user_metadata=u),this.request.post(n).send(r).end(a(e))},r.prototype.changePassword=function(t,e){var n,r;return s.check(t,{type:"object",message:"options parameter is not valid"},{connection:{type:"string",message:"connection option is required"},email:{type:"string",message:"email option is required"}}),s.check(e,{type:"function",message:"cb parameter is not valid"}),n=i(this.baseOptions.rootUrl,"dbconnections","change_password"),r=o.merge(this.baseOptions,["clientID"]).with(t,["email","connection"]),r=o.toSnakeCase(r,["auth0Client"]),this.request.post(n).send(r).end(a(e))},t.exports=r},function(t,e,n){function r(t,e){this.baseOptions=e,this.request=t}var i=n(3),o=n(1),s=n(4),a=n(6),u=n(5);r.prototype.buildVerifyUrl=function(t){var e,n;return s.check(t,{type:"object",message:"options parameter is not valid"},{connection:{type:"string",message:"connection option is required"},verificationCode:{type:"string",message:"verificationCode option is required"},phoneNumber:{optional:!1,type:"string",message:"phoneNumber option is required",condition:function(t){return!t.email}},email:{optional:!1,type:"string",message:"email option is required",condition:function(t){return!t.phoneNumber}}}),e=o.merge(this.baseOptions,["clientID","responseType","responseMode","redirectUri","scope","audience","_csrf","state","_intstate","protocol","nonce"]).with(t),this.baseOptions._sendTelemetry&&(e.auth0Client=this.request.getTelemetryData()),e=o.toSnakeCase(e,["auth0Client"]),n=a.stringify(e),i(this.baseOptions.rootUrl,"passwordless","verify_redirect","?"+n)},r.prototype.start=function(t,e){var n,r;return s.check(t,{type:"object",message:"options parameter is not valid"},{connection:{type:"string",message:"connection option is required"},send:{type:"string",message:"send option is required",values:["link","code"],value_message:"send is not valid ([link, code])"},phoneNumber:{optional:!0,type:"string",message:"phoneNumber option is required",condition:function(t){return"code"===t.send||!t.email}},email:{optional:!0,type:"string",message:"email option is required",condition:function(t){return"link"===t.send||!t.phoneNumber}},authParams:{optional:!0,type:"object",message:"authParams option is required"}}),s.check(e,{type:"function",message:"cb parameter is not valid"}),n=i(this.baseOptions.rootUrl,"passwordless","start"),r=o.merge(this.baseOptions,["clientID","responseType","redirectUri","scope"]).with(t),r.scope&&(r.authParams=r.authParams||{},r.authParams.scope=r.scope),r.redirectUri&&(r.authParams=r.authParams||{},r.authParams.redirect_uri=r.redirectUri),r.responseType&&(r.authParams=r.authParams||{},r.authParams.response_type=r.responseType),delete r.redirectUri,delete r.responseType,delete r.scope,r=o.toSnakeCase(r,["auth0Client","authParams"]),this.request.post(n).send(r).end(u(e))},r.prototype.verify=function(t,e){var n,r;return s.check(t,{type:"object",message:"options parameter is not valid"},{connection:{type:"string",message:"connection option is required"},verificationCode:{type:"string",message:"verificationCode option is required"},phoneNumber:{optional:!1,type:"string",message:"phoneNumber option is required",condition:function(t){return!t.email}},email:{optional:!1,type:"string",message:"email option is required",condition:function(t){return!t.phoneNumber}}}),s.check(e,{type:"function",message:"cb parameter is not valid"}),r=o.pick(t,["connection","verificationCode","phoneNumber","email","auth0Client"]),r=o.toSnakeCase(r,["auth0Client"]),n=i(this.baseOptions.rootUrl,"passwordless","verify"),this.request.post(n).send(r).end(u(e))},t.exports=r},function(t,e,n){function r(t,e,n){var r,i;if(void 0===s.getDocument().cookie||null===s.getDocument().cookie)throw new Error("cookie storage not available");if(n){var o=24*n*60*60*1e3;r=new Date,r.setTime(r.getTime()+o),i="; expires="+r.toGMTString()}else i="";s.getDocument().cookie=t+"="+a.encode(e)+i+"; path=/"}function i(t){var e,n,r,i=t+"=";if(void 0===s.getDocument().cookie||null===s.getDocument().cookie)throw new Error("cookie storage not available");for(r=s.getDocument().cookie.split(";"),e=0;e0&&t.warning("Following parameters are not allowed on the `/authorize` endpoint: ["+n.join(",")+"]"),e}function i(t,e){return o.pick(e,s)}var o=n(1),s=["realm","audience","client_id","client_secret","redirect_uri","scope","code","grant_type","username","password","refresh_token","assertion","client_assertion","client_assertion_type","code_verifier"],a=["connection","connection_scope","auth0Client","owp","device","realm","protocol","_csrf","_intstate","login_ticket","client_id","response_type","response_mode","redirect_uri","audience","scope","state","nonce","display","prompt","max_age","ui_locales","claims_locales","id_token_hint","login_hint","acr_values","claims","registration","request","request_uri","code_challenge","code_challenge_method"];t.exports={oauthTokenParams:i,oauthAuthorizeParams:r}},function(t,e,n){function r(t,e){this.plugins=e;for(var n=0;n 0, 43 | hint: $.mage.__("This is a required field.") 44 | }; 45 | } 46 | }, 47 | { 48 | name: "lastname", 49 | placeholder: $.mage.__("Last Name"), 50 | validator: function (firstname) { 51 | return { 52 | valid: firstname.length > 0, 53 | hint: $.mage.__("This is a required field.") 54 | }; 55 | } 56 | } 57 | ], 58 | auth: { 59 | redirectUrl: this.options.redirectUrl, 60 | responseType: 'code', 61 | params: { 62 | state: this.options.state, 63 | scope: 'openid' // Learn about scopes: https://auth0.com/docs/scopes 64 | } 65 | }, 66 | allowLogin: this.options.allowLogin, 67 | allowSignUp: this.options.allowSignUp, 68 | allowForgotPassword: this.options.allowForgotPassword 69 | } 70 | ); 71 | 72 | $(this.element).click(function (e) { 73 | e.preventDefault(); 74 | this.lock.show(); 75 | }.bind(this)); 76 | } 77 | }); 78 | 79 | return $.magefox.auth0; 80 | }); 81 | --------------------------------------------------------------------------------