Would you like to clone this notebook?

When you clone a notebook you are able to make changes without affecting the original notebook.

Cancel

7-Eleven API test

node v12.22.12
version: 1.0.3
endpointsharetweet
The following script will use the credential on line 12-13 (Email/Pasword) to get a access token and call "nearby stores" API.
const axios = require('axios'); const axiosCookieJarSupport = require('axios-cookiejar-support').default; const tough = require('tough-cookie'); const uuid = require('uuid').v4; const crypto = require('crypto'); const querystring = require('querystring'); const url = require('url'); // please don't modify the password const LOGIN_EMAIL = 'Alice84@1secmail.com'; const LOGIN_PASSWORD = 'LqkBqKLG6A_HC5U'; // AZURE AD D2C OAuth Flow // https://docs.microsoft.com/en-us/azure/active-directory-b2c/authorization-code-flow const AUTH_URL = 'https://auth.7eleven.com.au'; const AZURE_TENANT = 'e3aa5c67-b75d-4de2-b160-5d75da2ec18b'; // id registered by 7-Eleven in Azure AD B2C const AZURE_CLIENT_ID = '6a7ee7ae-e7ae-473b-9066-ec34fc5b541a'; const AZURE_CUSTOM_SIGNIN_POLICY = 'b2c_1a_v1_sign_in'; const REDIRECT_URL = 'au.com.7eleven.app://oauth/redirect'; const AUTHORIZE_SCOPE = 'openid https://auth.7eleven.com.au/api/user_impersonation offline_access'; const API_HOST = 'app.api.7eleven.com.au'; const BASE_API_URL = `https://${API_HOST}`; const AZURE_CLIENT_SECRET = '7613CF77-2BD5-4AD1-B7A0-52799BB23DF3'; const APP_VERSION = '2.0.1.11904'; const USER_AGENT = 'My 7-Eleven/11904 CFNetwork/978.0.7 Darwin/18.7.0'; const DEVICE_ID = uuid(); axiosCookieJarSupport(axios); const cookieJar = new tough.CookieJar(); function hmacSHA256(text) { const key = Buffer.from(AZURE_CLIENT_SECRET, 'utf8'); const hmac = crypto.createHmac('sha256', key); hmac.update(text); return Buffer.from(hmac.digest()).toString('base64'); } async function elevenRequest(method, urlPath, body, utcTime, accessToken) { const headers = { Host: API_HOST, 'x-device-os-version': '13.4', Accept: 'application/json', 'x-device-os': 'iOS', 'x-tz-offset': '36000', 'x-device-build-version': APP_VERSION, 'Accept-Language': 'en-au', 'Accept-Encoding': 'br, gzip, deflate', Date: utcTime, signature: hmacSHA256(body), 'x-device-uuid': DEVICE_ID, 'x-device-identifier': "iPad7,6", 'User-Agent': USER_AGENT, 'Content-Type': 'application/json', Connection: 'keep-alive', Authorization: `Bearer ${accessToken}`, }; return axios({ method, headers, data: body, url: `${BASE_API_URL}${urlPath}`, }); } // step 1: access authorize page (static HTML) const { data: authorizePageHtml } = await axios.get(`${AUTH_URL}/${AZURE_TENANT}/${AZURE_CUSTOM_SIGNIN_POLICY}/oauth2/v2.0/authorize`, { jar: cookieJar, withCredentials: true, params: { redirect_uri: REDIRECT_URL, client_id: AZURE_CLIENT_ID, response_type: 'code', prompt: 'login', state: 'pNb3esTxtjy12-bcfOFGW', // random string scope: AUTHORIZE_SCOPE, ui_theme: 'light' } }); // step 2: extract info from the HTML response const statePropertiesRegex = /"StateProperties=(\w+)"/; const stateProperties = statePropertiesRegex.exec(authorizePageHtml)[1]; const csrfTokenRegex = /"csrf":"(.+?)"/; const csrfToken = csrfTokenRegex.exec(authorizePageHtml)[1]; // step 3: login await axios.post(`${AUTH_URL}/${AZURE_TENANT}/${AZURE_CUSTOM_SIGNIN_POLICY}/SelfAsserted?tx=StateProperties=${stateProperties}&p=${AZURE_CUSTOM_SIGNIN_POLICY}`, querystring.stringify({ signInName: LOGIN_EMAIL, password: LOGIN_PASSWORD, request_type: 'RESPONSE', }), { headers: { 'X-CSRF-TOKEN': csrfToken, }, jar: cookieJar, withCredentials: true, }); // step 4: get authorization code try { await axios.get(`${AUTH_URL}/${AZURE_TENANT}/${AZURE_CUSTOM_SIGNIN_POLICY}/api/SelfAsserted/confirmed`, { params: { csrf_token: csrfToken, tx: `StateProperties=${stateProperties}`, p: AZURE_CUSTOM_SIGNIN_POLICY, }, jar: cookieJar, withCredentials: true, }); } catch (e) { // 302 redirection response to 7-Eleven's own app URL like ("au.com.7eleven.app://oauth/redirect") // what we need is just the code on URL const codeRegexp = /code=(.+)/; const authorizationCode = codeRegexp.exec(e.config.url)[1]; // step 5: exchange access token with authorization code const { data } = await axios.post(`${AUTH_URL}/${AZURE_TENANT}/${AZURE_CUSTOM_SIGNIN_POLICY}/oauth2/v2.0/token`, querystring.stringify({ code: authorizationCode, client_id: AZURE_CLIENT_ID, grant_type: 'authorization_code', redirect_uri: REDIRECT_URL, }) ); const accessToken = data.access_token; console.log(`Access Token:`); console.log(accessToken); // step 6: use access token to call API (nearby stores) const LATITUDE = "-38.14"; const LONGITUDE = "145.125"; const FUEL_TYPE = 'E10'; const utc = new Date().toUTCString(); const reqBody = `iOS,${APP_VERSION},GET,/api/stores/nearbyfuel,?fuel=${FUEL_TYPE}&lat=${LATITUDE}&lon=${LONGITUDE},${utc},${DEVICE_ID}`; const response = await elevenRequest('GET', `/api/stores/nearbyfuel?fuel=${FUEL_TYPE}&lat=${LATITUDE}&lon=${LONGITUDE}`, reqBody, utc, accessToken); console.log('Nearby Stores response:'); console.log(response.data); }
Loading…

no comments

    sign in to comment