equal-pfm-sdk-test
Version:
Equal PFM Angular SDK
226 lines (207 loc) • 8.75 kB
JavaScript
/**
* @typedef {Object} SDKCallbackData
* @property {string} eventType - Type of event ('PFM_SDK_CALLBACK', 'EQUAL_SDK_CALLBACK', etc.)
* @property {string} status - Status of the event ('ON_CLOSE', 'ERROR', etc.)
* @property {string} [statusCode] - Status code for error events
* @property {string} message - Message associated with the event
* @property {string} [transaction_id] - Optional transaction ID
* @property {string} [url] - Optional URL for navigation events
*/
/**
* @typedef {function(SDKCallbackData): void} SDKCallback - Callback function for SDK events
*/
var equalCloseEvent;
var equalErrorEvent;
var win;
var clientViewPort;
var intervalID;
const _PFM_APP_URL = {
"prod": "https://pfm.equal.in",
"uat": "https://uat.pfm.equal.in",
}
/**
* Checks if the device is running iOS
* @returns {boolean} True if the device is running iOS, false otherwise
* @private
*/
const _isIOSMobile = () => {
if (navigator.userAgent.match(/iPhone/i)
|| navigator.userAgent.match(/iPad/i)
|| navigator.userAgent.match(/iPod/i)) {
return true;
} else {
return false;
}
};
/**
* Checks if the device is a mobile device
* @returns {boolean} True if the device is mobile, false otherwise
* @private
*/
const _isMobileDevice = () => {
if (navigator.userAgent.match(/Android/i)
|| navigator.userAgent.match(/webOS/i)
|| navigator.userAgent.match(/iPhone/i)
|| navigator.userAgent.match(/iPad/i)
|| navigator.userAgent.match(/iPod/i)
|| navigator.userAgent.match(/BlackBerry/i)
|| navigator.userAgent.match(/Windows Phone/i)) {
return true;
} else {
return false;
}
};
/**
* Personal Finance Management SDK
* @constructor
* @param {string} token - Authentication token
* @param {string} env - Environment ('uat' or 'production')
*/
function PFMSDK(token, env) {
let equalDomain = _PFM_APP_URL.uat;
if (token && env) {
if (env.startsWith("production")) {
equalDomain = _PFM_APP_URL.prod;
}
}
/**
* Handles error messages and triggers callbacks
* @param {SDKCallback} callBack - Callback for the error event
* @param {string} statusCode - Error status code
* @param {string} errorMessage - Error message
*/
this.onErrorMessage = (callBack, statusCode, errorMessage) => {
if (callBack != null) {
callBack({ 'eventType': 'PFM_SDK_CALLBACK', 'status': 'ERROR', 'statusCode': statusCode, 'message': errorMessage });
}
if (equalErrorEvent != null) {
equalErrorEvent({ 'eventType': 'PFM_SDK_CALLBACK', 'status': 'ERROR', 'statusCode': statusCode, 'message': errorMessage });
}
}
/**
* Opens the PFM interface
* @param {SDKCallback} onErrorEvent - Callback for error events
* @param {SDKCallback} onCloseEvent - Callback for close events
* @returns {Promise<void>}
*/
this.openPFM = async (onErrorEvent, onCloseEvent) => {
if (_isMobileDevice()) {
this.addMobileViewPort();
}
equalErrorEvent = onErrorEvent;
equalCloseEvent = onCloseEvent;
this.openPFMSDK(null);
}
/**
* Adds mobile viewport meta tag
*/
this.addMobileViewPort = () => {
clientViewPort = document.querySelector("[name='viewport']");
if (clientViewPort != null) {
document.querySelector("[name='viewport']").remove();
}
var metaTag = document.createElement("meta");
metaTag.id = 'equal-viewport';
metaTag.name = "viewport";
metaTag.content =
"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0";
document.getElementsByTagName("head")[0].appendChild(metaTag);
}
/**
* Opens the PFM SDK iframe or popup
* @param {SDKCallback} callBack - Callback for SDK events
* @returns {Promise<void>}
*/
this.openPFMSDK = async (callBack) => {
if (token == null) {
let event = { 'eventType': 'PFM_SDK_CALLBACK', 'status': 'INVALID_SESSION_TOKEN', 'statusCode': "UNKNOWN", 'message': 'INVALID_SESSION_TOKEN' };
equalErrorEvent(event);
window.postMessage(event);
return;
}
const iframeUrl = equalDomain + "/pfm?access_token=" + token;
this.equalRootView = document.createElement('div');
this.equalRootView.id = 'equal-modal';
this.equalRootView.setAttribute("style", "z-index:100; display:block; padding-top:100px; position:fixed; left:0; top:0; width:100%; height:100%; overflow:auto; background-color:rgb(0,0,0); background-color:rgba(0,0,0,0.4)");
var div = document.createElement('div');
div.id = 'loading';
let width = '480px';
let height = '95%';
if (_isMobileDevice()) {
height = '99%'
width = '99%';
} else {
width = '99%';
height = '99%'
}
if (_isIOSMobile()) {
if ('visualViewport' in window) {
const VIEWPORT_VS_CLIENT_HEIGHT_RATIO = 0.75;
window.visualViewport.addEventListener('resize', function (event) {
if ((event.target.height * event.target.scale) / window.screen.height < VIEWPORT_VS_CLIENT_HEIGHT_RATIO) {
eIframe.contentWindow.postMessage({ 'eventType': 'EQUAL_KEYBOARD_EVENT', 'status': 'OPEN', 'height': (window.outerHeight - window.innerHeight) + 0 }, '*');
} else {
eIframe.contentWindow.postMessage({ 'eventType': 'EQUAL_KEYBOARD_EVENT', 'status': 'CLOSED' }, '*');
}
});
}
}
div.setAttribute("style", "position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); height: " + height + "; width: " + width + "; background: #ffffff; overflow: hidden; border-radius: 8px; cursor: pointer; box-shadow: 0 0 8px 8px rgb(0 0 0 / 10%);");
var eIframe = document.createElement("iframe");
eIframe.id = "pfmIframe"
eIframe.setAttribute("src", iframeUrl);
eIframe.setAttribute("style", "height: 100%; width: 100%;");
eIframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms allow-popups");
eIframe.setAttribute("frameBorder", "0");
div.appendChild(eIframe);
this.equalRootView.appendChild(div);
document.body.appendChild(this.equalRootView);
// Add URL change listener
eIframe.onload = function() {
try {
const currentUrl = eIframe.contentWindow.location.href;
if (currentUrl.contains('pfm/close')) {
const uri = new URL(currentUrl);
const message = uri.searchParams.get('message');
const status_code = uri.searchParams.get('status_code');
const status = uri.searchParams.get('status');
const eventData = {
type: 'PFM_SDK_CALLBACK',
message: message,
status_code: status_code,
status: status
};
if (status === 'CLOSED') {
if (equalCloseEvent != null) equalCloseEvent(eventData);
window.postMessage(eventData);
} else if (status === 'ERROR') {
if (equalErrorEvent != null) equalErrorEvent(eventData);
window.postMessage(eventData);
}
if (this.equalRootView != null && document.body.contains(this.equalRootView)) {
document.body.removeChild(this.equalRootView);
}
if (document.querySelector("[id='equal-viewport']") != null) {
document.querySelector("[id='equal-viewport']").remove();
}
this.equalRootView = null;
}
} catch (e) {
console.error('Error accessing iframe URL:', e);
const errorEvent = {
type: 'PFM_SDK_CALLBACK',
status: 'ERROR',
message: e.toString()
};
if (equalErrorEvent != null) equalErrorEvent(errorEvent);
window.postMessage(errorEvent);
}
}.bind(this);
}
}
// Make PFMSDK available for module systems
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = PFMSDK;
} else {
window.PFMSDK = PFMSDK;
}