Skip to content

Commit

Permalink
Added load of API key by url
Browse files Browse the repository at this point in the history
  • Loading branch information
juanatsap committed Mar 26, 2021
1 parent 52e2cb9 commit 437f9c9
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 127 deletions.
7 changes: 5 additions & 2 deletions docs/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ This section shows the project file structure with a brief explanation of the ma
│   ├── ui.js
│   ├── utils.js
│   ├── gigya-raas.js
│   ├── dynamic-apikey.js
│   └── main.js
|
├── less
Expand Down Expand Up @@ -73,8 +74,8 @@ This section shows the project file structure with a brief explanation of the ma
3. __docs__: This set of docs.
4. __html__: Main HTML content of the site. The navigation bar and logged sample content it's stored here.
5. __img__: It contains all the images for the project.
6. __js__: It contains the files with the logic of the site. It has a specific file for Gigya functions (gigya-raas.js), another one to make the site demo work (engine.js), and a last one (main.js), that will start all the process.
7. __less__: css files are automatically generated using these less files as source. Using a proper plugin, any modification over these files will generate a new css set of files in the /css folder.
6. __js__: It contains the files with the logic of the site. It has a specific file for Gigya functions (gigya-raas.js), and other set of files to make the site demo work (like engine.js or ui.js), and a last one (main.js), that will start all the process.
7. __less__: All style files are automatically generated using these less files as source. Using a proper plugin, any modification over these files will generate a new css set of files in the /css folder.
8. __index.html__: This is the main page of the site. It contains all the elements needed to manage both logged and not logged states for the user.
9. __edit-profile.html__: The edit profile page. This page will be shown only for logged in users, being redirected to the index.html page when the user's session is not present.
10. __Other files__: The rest of the files are or README files, or editor configuration files, like the .eslintrc.js. Git files are also there, and they can all be removed, and the project will work as expected.
Expand Down Expand Up @@ -219,6 +220,8 @@ The project uses vanilla javascript for all their interactions, although it use

1. **gigya-raas.js**: This file contains all typical gigya functions in a RaaS process. You will find here the triggers for the login, the registration, or the reset password process. __This is the file you want to copy in your project to have a set of default gigya functions__.

1. **dynamic-apikey.js**: This file contains some specific logic to be able to switch between api keys in realtime. __This file is not needed for a regular gigya implementation__, although it's interesting to understand how to load dinamically Gigya api keys into a site.

1. **ui.js**: This file contains all the logic related to the UI stuff, like re-painting the screen, dealing with popups, etc.

1. **utils.js**: This file contains several standard util functions.
Expand Down
1 change: 1 addition & 0 deletions edit-profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ <h3 class="title site-title has-text-grey is-hidden">

<!-- Framework files -->
<script type="text/javascript" lang="javascript" src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script type="text/javascript" lang="javascript" src="js/dynamic-apikey.js"></script>
<script type="text/javascript" lang="javascript" src="js/gigya-raas.js"></script>
<script type="text/javascript" lang="javascript" src="js/engine.js"></script>
<script type="text/javascript" lang="javascript" src="js/utils.js"></script>
Expand Down
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ <h3 class="title site-title has-text-grey">

<!-- Framework files -->
<script type="text/javascript" lang="javascript" src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script type="text/javascript" lang="javascript" src="js/dynamic-apikey.js"></script>
<script type="text/javascript" lang="javascript" src="js/gigya-raas.js"></script>
<script type="text/javascript" lang="javascript" src="js/engine.js"></script>
<script type="text/javascript" lang="javascript" src="js/utils.js"></script>
Expand Down
140 changes: 140 additions & 0 deletions js/dynamic-apikey.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/**
* ----------------
* # UI JS File
* ----------------
*
* This file contains some specific logic to be able to switch between api keys in realtime.
* __This file is not needed for a regular gigya implementation__, although it's interesting
* to understand how to load dinamically Gigya api keys into a site.
*
* @link https://github.com/gigya/cdc-starter-kit/blob/master/js/dynamic-apikey.js
* @file This file defines all UI functions to be used in the website.
* @author [email protected]
* @since 1.1.0
*/

/** *****************************************************/
// 6. DYNAMIC API Key FUNCTIONS
/** *****************************************************/

/**
* Changes the API key of the site, writing into the local storage the value of this new API Key and reloading the page.
*/
function changeAPIKey() {
//
log("X. - Changing API KEy.... ", "RELOAD ALL PAGE");

// Show the loading button
const changeAPIKeyButton = query(
".change-api-key-modal .modal-card-foot .change-api-key-button"
);
changeAPIKeyButton.classList.add("is-loading");

// Take the api key
const apiKey = query(".change-api-key-modal .api-key-input").value;

// Store api key in local storage and reload the page (it will load the new api key)
setInLocalStorage("reload-with-apikey", apiKey);

// Reload page
window.location.href = window.location.href;
}

/**
* Loads dynamically into the body of the page the Gigya WebSDK Js file for the incoming API Key.
* @param {string} apiKey Gigya API Key
*/
function loadGigyaForApiKey(apiKey) {
// Adding new Gigya script from parameters
log("2. Load Gigya File with apiKey " + apiKey, "LOAD GIGYA FILE");

var newScript = document.createElement("script");
newScript.setAttribute(
"src",
"https://cdns.gigya.com/js/gigya.js?apikey=" + apiKey
);
document.body.appendChild(newScript);

// Check if loaded properly, if don't, delete the localstorage param and reload the page again
setTimeout(checkIfGigyaLoaded, 1500);
}

/**
* Clears custom api key from local storage and reloads the page with the default one
*/
function clearCustomApiKey() {
// Show the loading button
const resetAPIKeyButton = query(
".change-api-key-modal .reset-api-key-button"
);
if (resetAPIKeyButton) {
resetAPIKeyButton.classList.add("is-loading");
}

localStorage.removeItem("reload-with-apikey");
window.location.href = window.location.href;
}

/**
* Check if loaded properly, if don't, delete the localstorage param and reload the page again
*/
function checkIfGigyaLoaded() {
if (typeof gigya === "undefined" || gigya.isReady === false) {
// Clear wrong api key
const apiKeyFromLocalStorage = getFromLocalStorage("reload-with-apikey");
if (
apiKeyFromLocalStorage &&
apiKeyFromLocalStorage !== null &&
apiKeyFromLocalStorage !== ""
) {
console.error(
"Invalid Api Key %c%s %c ... resetting to original state with api key %c%s",
"font-weight: bold;",
apiKeyFromLocalStorage,
"font-weight: normal",
"font-weight: bold; color: #257942",
config.apiKey
);
clearCustomApiKey();
}
}
}

/**
* Validates (Via backend) the incoming API Key. If the backend call is broken, it degrades to a valid API Key, that it will fail later when it's tried to be loaded.
* @param {string} apiKey the API Key to validate
* @returns {boolean} Validity of the API Key
*/
function validateAPIKey(apiKey) {
var validApiKeyResponse = "";
//
log("X. - Validating api key " + apiKey + "... ", "BACKEND CALL");

// TODO Include this as part of the call!
const id_token = "";

// We make a SYNCHRONOUS url call (only few millis)
const baseDomainsForApiKey =
typeof gigya !== "undefined" ? gigya.partnerSettings.baseDomains : null;
const validateAPIKeyUrl = `https://juan.gigya-cs.com/api/cdc-starter-kit/validate-apikey.php?apikey=${apiKey}&baseDomains=${baseDomainsForApiKey}&id_token=${id_token}`;
var request = new XMLHttpRequest();
request.open("GET", validateAPIKeyUrl, false); // `false` makes the request synchronous

try {
request.send(null);
} catch (error) {
// console.log('isInvalid URL');
}

if (request.status === 200) {
validApiKeyResponse = request.responseText;
// console.log(validApiKeyResponse);
log("Is this a valid api key ? : " + validApiKeyResponse);
} else {
// If for whatever reason is broken, we send true (no backend validation)
validApiKeyResponse = "OK";
}
return validApiKeyResponse;
}

/** *****************************************************/
144 changes: 19 additions & 125 deletions js/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,26 @@ function loadConfigFromFile(out) {
out.lang = storedLanguage;
}

log("2. Check URL Params ");
// After having the initial configuration, we check if we have params that will override these properties.
// Properties accepted by the app are:
//
// - apiKey
// - screensetPrefix
// - showLog
// - showEventsLog
// - showSampleContent

// 2. Check if we have the dynamic ApiKey in the url. If yes, substitute in the url
const apiKeyFromQueryString = getFromQueryString("apiKey");
var isValidApiKey = false;
if (apiKeyFromQueryString && apiKeyFromQueryString !== null) {



isValidApiKey = validateAPIKey(apiKeyFromQueryString);
isValidApiKey = validateAPIKey(apiKeyFromQueryString) === "OK";
log("VALID API Key ?" + isValidApiKey + "...", "BACKEND CALL RESPONSE");

// Checking validity status and modify the change api key button accordingly.
if (isValidApiKey === "OK") {
if (isValidApiKey === true) {

// Enable the button and show the proper class for the input text
out.apiKeyFromQueryString = apiKeyFromQueryString;
Expand Down Expand Up @@ -133,10 +141,7 @@ function loadConfigFromFile(out) {
showEventsLog = showEventLogsFromQueryString === "true";
}

// 7. Store the exit of the file as a global object to be used along the site
window.config = out;
log("1. Load Configuration from file ", "GET ACCOUNT INFO");

// API KEY + GIGYA LOAD SECTION
// Checking if we have api key in local storage
const apiKeyFromLocalStorage = getFromLocalStorage("reload-with-apikey");

Expand All @@ -148,13 +153,18 @@ function loadConfigFromFile(out) {
// We take the url of the query string and remove the dynamic one
// setInLocalStorage("reload-with-apikey", apiKeyFromQueryString);
apiKey = apiKeyFromQueryString;
// out.apiKey = apiKeyFromQueryString;
} else {

if (apiKeyFromLocalStorage && apiKeyFromLocalStorage !== null && apiKeyFromLocalStorage !== "") {
apiKey = apiKeyFromLocalStorage;
}
}

// 7. Store the exit of the file as a global object to be used along the site
window.config = out;
// debugger;
log("3. Load Gigya for api key: " + apiKey, "LOAD GIGYA FILE");
loadGigyaForApiKey(apiKey);
}

Expand Down Expand Up @@ -400,120 +410,4 @@ function deleteCurrentAccount() {
}
},
});
}

/** *****************************************************/
// 6. DYNAMIC API Key FUNCTIONS
/** *****************************************************/

/**
* Changes the API key of the site, writing into the local storage the value of this new API Key and reloading the page.
*/
function changeAPIKey() {
//
log("X. - Changing API KEy.... ", "RELOAD ALL PAGE");

// Show the loading button
const changeAPIKeyButton = query(".change-api-key-modal .modal-card-foot .change-api-key-button");
changeAPIKeyButton.classList.add("is-loading");

// Take the api key
const apiKey = query(".change-api-key-modal .api-key-input").value;

// Store api key in local storage and reload the page (it will load the new api key)
setInLocalStorage("reload-with-apikey", apiKey);

// Reload page
window.location.href = window.location.href;


}

/**
* Loads dynamically into the body of the page the Gigya WebSDK Js file for the incoming API Key.
* @param {string} apiKey Gigya API Key
*/
function loadGigyaForApiKey(apiKey) {

// Adding new Gigya script from parameters
log("2. Load Gigya File with apiKey " + apiKey, "LOAD GIGYA FILE");

var newScript = document.createElement('script');
newScript.setAttribute('src', 'https://cdns.gigya.com/js/gigya.js?apikey=' + apiKey);
document.body.appendChild(newScript);

// Check if loaded properly, if don't, delete the localstorage param and reload the page again
setTimeout(checkIfGigyaLoaded, 1000);
}

/**
* Clears custom api key from local storage and reloads the page with the default one
*/
function clearCustomApiKey() {

// Show the loading button
const resetAPIKeyButton = query(".change-api-key-modal .reset-api-key-button");
if (resetAPIKeyButton) {
resetAPIKeyButton.classList.add("is-loading");
}

localStorage.removeItem("reload-with-apikey");
window.location.href = window.location.href;
}

/**
* Check if loaded properly, if don't, delete the localstorage param and reload the page again
*/
function checkIfGigyaLoaded() {
if (typeof gigya === 'undefined' || gigya.isReady === false) {

// Clear wrong api key
const apiKeyFromLocalStorage = getFromLocalStorage("reload-with-apikey");
if (apiKeyFromLocalStorage && apiKeyFromLocalStorage !== null && apiKeyFromLocalStorage !== '') {
console.error('Invalid Api Key %c%s %c ... resetting to original state with api key %c%s', 'font-weight: bold;', apiKeyFromLocalStorage, 'font-weight: normal', 'font-weight: bold; color: #257942', config.apiKey);
clearCustomApiKey();
}

}
}

/**
* Validates (Via backend) the incoming API Key. If the backend call is broken, it degrades to a valid API Key, that it will fail later when it's tried to be loaded.
* @param {string} apiKey the API Key to validate
* @returns {boolean} Validity of the API Key
*/
function validateAPIKey(apiKey) {

var validApiKeyResponse = "";
//
log("X. - Validating api key " + apiKey + "... ", "BACKEND CALL");

// TODO Include this as part of the call!
const id_token = '';

// We make a SYNCHRONOUS url call (only few millis)
const baseDomainsForApiKey = typeof gigya !== "undefined" ? gigya.partnerSettings.baseDomains : null;
const validateAPIKeyUrl = `https://juan.gigya-cs.com/api/cdc-starter-kit/validate-apikey.php?apikey=${apiKey}&baseDomains=${baseDomainsForApiKey}&id_token=${id_token}`;
var request = new XMLHttpRequest();
request.open("GET", validateAPIKeyUrl, false); // `false` makes the request synchronous

try {
request.send(null);
} catch (error) {
// console.log('isInvalid URL');
}

if (request.status === 200) {
validApiKeyResponse = request.responseText;
// console.log(validApiKeyResponse);
log("Is this a valid api key ? : " + validApiKeyResponse);

} else {

// If for whatever reason is broken, we send true (no backend validation)
validApiKeyResponse = "OK";
}
return validApiKeyResponse;
}

/** *****************************************************/
}

0 comments on commit 437f9c9

Please sign in to comment.