UNPKG

jslib-nightly

Version:

SheerID JavaScript Library

1,296 lines (1,229 loc) 1.06 MB
import React, { useRef, useCallback, useEffect, useMemo, cloneElement, Component, useLayoutEffect, useReducer, PureComponent, useState, forwardRef, useImperativeHandle, Fragment as Fragment$2, Suspense as Suspense$2 } from 'react'; import { FormattedHTMLMessage, injectIntl, IntlProvider, FormattedMessage } from 'react-intl'; import 'react-intl/locale-data/en.js'; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var clone_1 = createCommonjsModule(function (module) { var clone = (function() { function _instanceof(obj, type) { return type != null && obj instanceof type; } var nativeMap; try { nativeMap = Map; } catch(_) { // maybe a reference error because no `Map`. Give it a dummy value that no // value will ever be an instanceof. nativeMap = function() {}; } var nativeSet; try { nativeSet = Set; } catch(_) { nativeSet = function() {}; } var nativePromise; try { nativePromise = Promise; } catch(_) { nativePromise = function() {}; } /** * Clones (copies) an Object using deep copying. * * This function supports circular references by default, but if you are certain * there are no circular references in your object, you can save some CPU time * by calling clone(obj, false). * * Caution: if `circular` is false and `parent` contains circular references, * your program may enter an infinite loop and crash. * * @param `parent` - the object to be cloned * @param `circular` - set to true if the object to be cloned may contain * circular references. (optional - true by default) * @param `depth` - set to a number if the object is only to be cloned to * a particular depth. (optional - defaults to Infinity) * @param `prototype` - sets the prototype to be used when cloning an object. * (optional - defaults to parent prototype). * @param `includeNonEnumerable` - set to true if the non-enumerable properties * should be cloned as well. Non-enumerable properties on the prototype * chain will be ignored. (optional - false by default) */ function clone(parent, circular, depth, prototype, includeNonEnumerable) { if (typeof circular === 'object') { depth = circular.depth; prototype = circular.prototype; includeNonEnumerable = circular.includeNonEnumerable; circular = circular.circular; } // maintain two arrays for circular references, where corresponding parents // and children have the same index var allParents = []; var allChildren = []; var useBuffer = typeof Buffer != 'undefined'; if (typeof circular == 'undefined') circular = true; if (typeof depth == 'undefined') depth = Infinity; // recurse this function so we don't reset allParents and allChildren function _clone(parent, depth) { // cloning null always returns null if (parent === null) return null; if (depth === 0) return parent; var child; var proto; if (typeof parent != 'object') { return parent; } if (_instanceof(parent, nativeMap)) { child = new nativeMap(); } else if (_instanceof(parent, nativeSet)) { child = new nativeSet(); } else if (_instanceof(parent, nativePromise)) { child = new nativePromise(function (resolve, reject) { parent.then(function(value) { resolve(_clone(value, depth - 1)); }, function(err) { reject(_clone(err, depth - 1)); }); }); } else if (clone.__isArray(parent)) { child = []; } else if (clone.__isRegExp(parent)) { child = new RegExp(parent.source, __getRegExpFlags(parent)); if (parent.lastIndex) child.lastIndex = parent.lastIndex; } else if (clone.__isDate(parent)) { child = new Date(parent.getTime()); } else if (useBuffer && Buffer.isBuffer(parent)) { if (Buffer.allocUnsafe) { // Node.js >= 4.5.0 child = Buffer.allocUnsafe(parent.length); } else { // Older Node.js versions child = new Buffer(parent.length); } parent.copy(child); return child; } else if (_instanceof(parent, Error)) { child = Object.create(parent); } else { if (typeof prototype == 'undefined') { proto = Object.getPrototypeOf(parent); child = Object.create(proto); } else { child = Object.create(prototype); proto = prototype; } } if (circular) { var index = allParents.indexOf(parent); if (index != -1) { return allChildren[index]; } allParents.push(parent); allChildren.push(child); } if (_instanceof(parent, nativeMap)) { parent.forEach(function(value, key) { var keyChild = _clone(key, depth - 1); var valueChild = _clone(value, depth - 1); child.set(keyChild, valueChild); }); } if (_instanceof(parent, nativeSet)) { parent.forEach(function(value) { var entryChild = _clone(value, depth - 1); child.add(entryChild); }); } for (var i in parent) { var attrs; if (proto) { attrs = Object.getOwnPropertyDescriptor(proto, i); } if (attrs && attrs.set == null) { continue; } child[i] = _clone(parent[i], depth - 1); } if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(parent); for (var i = 0; i < symbols.length; i++) { // Don't need to worry about cloning a symbol because it is a primitive, // like a number or string. var symbol = symbols[i]; var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { continue; } child[symbol] = _clone(parent[symbol], depth - 1); if (!descriptor.enumerable) { Object.defineProperty(child, symbol, { enumerable: false }); } } } if (includeNonEnumerable) { var allPropertyNames = Object.getOwnPropertyNames(parent); for (var i = 0; i < allPropertyNames.length; i++) { var propertyName = allPropertyNames[i]; var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); if (descriptor && descriptor.enumerable) { continue; } child[propertyName] = _clone(parent[propertyName], depth - 1); Object.defineProperty(child, propertyName, { enumerable: false }); } } return child; } return _clone(parent, depth); } /** * Simple flat clone using prototype, accepts only objects, usefull for property * override on FLAT configuration object (no nested props). * * USE WITH CAUTION! This may not behave as you wish if you do not know how this * works. */ clone.clonePrototype = function clonePrototype(parent) { if (parent === null) return null; var c = function () {}; c.prototype = parent; return new c(); }; // private utility functions function __objToStr(o) { return Object.prototype.toString.call(o); } clone.__objToStr = __objToStr; function __isDate(o) { return typeof o === 'object' && __objToStr(o) === '[object Date]'; } clone.__isDate = __isDate; function __isArray(o) { return typeof o === 'object' && __objToStr(o) === '[object Array]'; } clone.__isArray = __isArray; function __isRegExp(o) { return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; } clone.__isRegExp = __isRegExp; function __getRegExpFlags(re) { var flags = ''; if (re.global) flags += 'g'; if (re.ignoreCase) flags += 'i'; if (re.multiline) flags += 'm'; return flags; } clone.__getRegExpFlags = __getRegExpFlags; return clone; })(); if (module.exports) { module.exports = clone; } }); function deepClone(obj) { return clone_1(obj); } /** * Avoid "can't access property of undefined" errors in a more readable way. * @param fn Function that wraps a nested property access * @param defaultVal Optional - the value to return if property access failed */ function getSafe(fn, defaultVal) { try { return fn(); } catch (e) { return defaultVal; } } /** * Performs a deep merge of `source` into `target`. * Mutates `target` only but not its objects and arrays. * * @author inspired from https://gist.github.com/ahtcx/0cd94e62691f539160b32ecda18af3d6#gistcomment-3120712 */ function deepMerge(...objects) { const isObject = (obj) => obj && typeof obj === 'object'; function deepMergeInner(target, source) { Object.keys(source).forEach((key) => { const targetValue = target[key]; const sourceValue = source[key]; if (Array.isArray(targetValue) && Array.isArray(sourceValue)) { target[key] = targetValue.concat(sourceValue); // eslint-disable-line } else if (isObject(targetValue) && isObject(sourceValue)) { target[key] = deepMergeInner(Object.assign({}, targetValue), sourceValue); // eslint-disable-line } else { target[key] = sourceValue; // eslint-disable-line } }); return target; } if (objects.length < 2) { throw new Error('deepMerge: this function expects at least 2 objects to be provided'); } if (objects.some(object => !isObject(object))) { throw new Error('deepMerge: all values should be of type "object"'); } const target = objects.shift(); let source; // eslint-disable-next-line while (source = objects.shift()) { deepMergeInner(target, source); } return target; } let logLevel = 4; // default let prefix = ''; const logLevels = { info: 1, log: 2, warn: 3, error: 4, }; const colors = { info: '#26c1db', log: '#09f979', warn: '#f6b13f', error: '#e12046', }; const standardStyles = 'color: white; font-weight: bold; padding: 2px 10px;'; let reduxStore; const logAPIResponseTime = (url, time) => { if (window.NREUM) { window.NREUM.addPageAction('API-calls-timing', { api_call: url, api_response_time: time, }); } else { warn('Off-site logging not available.'); } }; const isError = e => e && e.stack && e.message; /** * @param error Primary, details error message or full error object * @param errorMessageGroup Use this to group error messages together with a string that does not vary as frequently. * Do not pass programId, verificationId, etc */ const error = (err, errorMessageGroup) => { if (logLevel <= 4) { if (!err) { console.error(new Error('An error must be supplied')); return; } let errorObj; if (typeof err === 'string') errorObj = new Error(err); if (isError(err)) errorObj = err; if (!errorObj) errorObj = new Error('Unknown error'); let usefulAttributes = { errorMessageGroup }; try { if (reduxStore && reduxStore.getState) { const state = reduxStore.getState(); const errorIds = getSafe(() => state.verificationResponse.errorIds); usefulAttributes = { errorMessageGroup, programId: getSafe(() => state.programId), isLoading: getSafe(() => state.isLoading), isErrored: getSafe(() => state.isErrored), errorIdsFromVerRsp: (Array.isArray(errorIds) ? errorIds.join : undefined), verificationId: getSafe(() => state.verificationResponse.verificationId), currentStep: getSafe(() => state.verificationResponse.currentStep), locale: getSafe(() => state.programTheme.intl.locale), isTestMode: getSafe(() => state.programTheme.isTestMode), openOrgSearchEnabled: getSafe(() => state.programTheme.openOrgSearchEnabled), jslibVerActual: getSafe(() => window.sheerIdPubV, '?'), jslibVerRequested: getSafe(() => window.sheerIdReqV, '?'), }; } } catch (e) { // Some invokers of logger.error() don't use redux console.warn('Unable to assemble useful error attributes', e); // eslint-disable-line } try { if (window.NREUM) { window.NREUM.noticeError(errorObj, usefulAttributes); } else { // Some customers can't install New Relic so this is not an error: warn('Off-site logging not available.'); // eslint-disable-line } } catch (e) { console.error('Unable to send error to remote service', e); // eslint-disable-line } console.error(`%c${prefix} error`, `background: ${colors.error};${standardStyles}`, errorObj, usefulAttributes); // eslint-disable-line } }; const warn = (...args) => { if (logLevel <= 3) { console.warn(`%c${prefix} warn`, `background: ${colors.warn};${standardStyles}`, ...args); // eslint-disable-line } }; const log = (...args) => { if (logLevel <= 2) { console.log(`%c${prefix} log`, `background: ${colors.log};${standardStyles}`, ...args); // eslint-disable-line } }; const info = (...args) => { if (logLevel <= 1) { console.log(`%c${prefix} info`, `background: ${colors.info};${standardStyles}`, ...args); // eslint-disable-line } }; const logger = { error, warn, log, info, logAPIResponseTime, setLogLevel: (desiredLogLevel) => { if (!logLevels.hasOwnProperty(desiredLogLevel)) { throw new Error(`Unknown logLevel '${desiredLogLevel}'`); } logLevel = logLevels[desiredLogLevel]; console.log(`%c${prefix} log level set to ${desiredLogLevel}`, `background: ${colors[desiredLogLevel]};${standardStyles}`); }, setPrefix: (thisPrefix) => { prefix = thisPrefix; }, init: (store) => { reduxStore = store; }, }; /** * @description List of locales supported by the library, for runtime checks. */ const Locales = ['ar', 'bg', 'cs', 'da', 'de', 'el', 'en-GB', 'en-US', 'es-ES', 'es', 'fi', 'fr-CA', 'fr', 'ga', 'hr', 'hu', 'id', 'it', 'iw', 'ja', 'ko', 'lo', 'lt', 'ms', 'nl', 'no', 'pl', 'pt-BR', 'pt', 'ru', 'sk', 'sl', 'sr', 'sv', 'th', 'tr', 'zh-HK', 'zh']; var VerificationStepsEnum; (function (VerificationStepsEnum) { VerificationStepsEnum["collectStudentPersonalInfo"] = "collectStudentPersonalInfo"; VerificationStepsEnum["collectTeacherPersonalInfo"] = "collectTeacherPersonalInfo"; VerificationStepsEnum["collectMemberPersonalInfo"] = "collectMemberPersonalInfo"; VerificationStepsEnum["collectMilitaryStatus"] = "collectMilitaryStatus"; VerificationStepsEnum["collectActiveMilitaryPersonalInfo"] = "collectActiveMilitaryPersonalInfo"; VerificationStepsEnum["collectInactiveMilitaryPersonalInfo"] = "collectInactiveMilitaryPersonalInfo"; VerificationStepsEnum["collectSeniorPersonalInfo"] = "collectSeniorPersonalInfo"; VerificationStepsEnum["collectAgePersonalInfo"] = "collectAgePersonalInfo"; VerificationStepsEnum["collectFirstResponderPersonalInfo"] = "collectFirstResponderPersonalInfo"; VerificationStepsEnum["collectMedicalProfessionalPersonalInfo"] = "collectMedicalProfessionalPersonalInfo"; VerificationStepsEnum["collectEmployeePersonalInfo"] = "collectEmployeePersonalInfo"; VerificationStepsEnum["collectSocialSecurityNumber"] = "collectSocialSecurityNumber"; VerificationStepsEnum["cancelSocialSecurityNumber"] = "cancelSocialSecurityNumber"; VerificationStepsEnum["collectDriverLicensePersonalInfo"] = "collectDriverLicensePersonalInfo"; VerificationStepsEnum["collectGeneralIdentityPersonalInfo"] = "collectGeneralIdentityPersonalInfo"; VerificationStepsEnum["collectHybridIdentityPersonalInfo"] = "collectHybridIdentityPersonalInfo"; VerificationStepsEnum["collectLicensedProfessionalPersonalInfo"] = "collectLicensedProfessionalPersonalInfo"; VerificationStepsEnum["docUpload"] = "docUpload"; VerificationStepsEnum["pending"] = "pending"; VerificationStepsEnum["docReviewLimitExceeded"] = "docReviewLimitExceeded"; VerificationStepsEnum["success"] = "success"; VerificationStepsEnum["error"] = "error"; VerificationStepsEnum["sso"] = "sso"; VerificationStepsEnum["smsLoop"] = "smsLoop"; VerificationStepsEnum["emailLoop"] = "emailLoop"; VerificationStepsEnum["cancelEmailLoop"] = "cancelEmailLoop"; })(VerificationStepsEnum || (VerificationStepsEnum = {})); const VerificationSteps = Object.values(VerificationStepsEnum); // For runtime checks var TryAgainStepsEnum; (function (TryAgainStepsEnum) { TryAgainStepsEnum["docUpload"] = "docUpload"; TryAgainStepsEnum["pending"] = "pending"; TryAgainStepsEnum["error"] = "error"; })(TryAgainStepsEnum || (TryAgainStepsEnum = {})); const TryAgainSteps = Object.values(TryAgainStepsEnum); // For runtime checks var MockStepsEnum; (function (MockStepsEnum) { MockStepsEnum["loading"] = "loading"; })(MockStepsEnum || (MockStepsEnum = {})); const MockSteps = [ ...Object.values(VerificationStepsEnum), ...Object.values(MockStepsEnum), ]; var SegmentEnum; (function (SegmentEnum) { SegmentEnum["STUDENT"] = "student"; SegmentEnum["MILITARY"] = "military"; SegmentEnum["TEACHER"] = "teacher"; SegmentEnum["MEMBER"] = "member"; SegmentEnum["SENIOR"] = "senior"; SegmentEnum["AGE"] = "age"; SegmentEnum["FIRST_RESPONDER"] = "firstResponder"; SegmentEnum["MEDICAL"] = "medical"; SegmentEnum["EMPLOYMENT"] = "employment"; SegmentEnum["IDENTITY"] = "identity"; SegmentEnum["LICENSED_PROFESSIONAL"] = "licensedProfessional"; })(SegmentEnum || (SegmentEnum = {})); const Segments = Object.values(SegmentEnum); // For runtime checks var SubSegmentEnum; (function (SubSegmentEnum) { SubSegmentEnum["ACTIVE_DUTY"] = "activeDuty"; SubSegmentEnum["VETERAN"] = "veteran"; SubSegmentEnum["RESERVIST"] = "reservist"; SubSegmentEnum["MILITARY_RETIREE"] = "retiree"; SubSegmentEnum["MILITARY_FAMILY"] = "militaryFamily"; SubSegmentEnum["FIREFIGHTER"] = "fireFighter"; SubSegmentEnum["POLICE"] = "police"; SubSegmentEnum["EMT"] = "emt"; SubSegmentEnum["NURSE"] = "nurse"; SubSegmentEnum["DRIVER_LICENSE"] = "driverLicense"; SubSegmentEnum["GENERAL_IDENTITY"] = "generalIdentity"; SubSegmentEnum["HYBRID_IDENTITY"] = "hybridIdentity"; })(SubSegmentEnum || (SubSegmentEnum = {})); Object.values(SubSegmentEnum); // For runtime checks var MilitaryStatusDefaultMessagesEnum; (function (MilitaryStatusDefaultMessagesEnum) { MilitaryStatusDefaultMessagesEnum["ACTIVE_DUTY"] = "Active Duty"; MilitaryStatusDefaultMessagesEnum["MILITARY_RETIREE"] = "Military Retiree"; MilitaryStatusDefaultMessagesEnum["RESERVIST"] = "Reservist"; MilitaryStatusDefaultMessagesEnum["VETERAN"] = "Veteran"; MilitaryStatusDefaultMessagesEnum["MILITARY_FAMILY"] = "Registered Military Dependent"; })(MilitaryStatusDefaultMessagesEnum || (MilitaryStatusDefaultMessagesEnum = {})); var FirstResponderStatusDefaultMessagesEnum; (function (FirstResponderStatusDefaultMessagesEnum) { FirstResponderStatusDefaultMessagesEnum["FIREFIGHTER"] = "Firefighter"; FirstResponderStatusDefaultMessagesEnum["POLICE"] = "Police"; FirstResponderStatusDefaultMessagesEnum["EMT"] = "EMT"; })(FirstResponderStatusDefaultMessagesEnum || (FirstResponderStatusDefaultMessagesEnum = {})); var MedicalProfessionalStatusDefaultMessagesEnum; (function (MedicalProfessionalStatusDefaultMessagesEnum) { MedicalProfessionalStatusDefaultMessagesEnum["NURSE"] = "Nurse"; MedicalProfessionalStatusDefaultMessagesEnum["DOCTOR"] = "Doctor"; MedicalProfessionalStatusDefaultMessagesEnum["OTHER_HEALTH_WORKER"] = "Other Health Worker"; })(MedicalProfessionalStatusDefaultMessagesEnum || (MedicalProfessionalStatusDefaultMessagesEnum = {})); Object.values(MilitaryStatusDefaultMessagesEnum); // For runtime checks Object.values(FirstResponderStatusDefaultMessagesEnum); // For runtime checks Object.values(MedicalProfessionalStatusDefaultMessagesEnum); // For runtime checks var FieldIdEnum; (function (FieldIdEnum) { FieldIdEnum["firstName"] = "firstName"; FieldIdEnum["lastName"] = "lastName"; FieldIdEnum["memberId"] = "memberId"; FieldIdEnum["organization"] = "organization"; FieldIdEnum["birthDate"] = "birthDate"; FieldIdEnum["email"] = "email"; FieldIdEnum["phoneNumber"] = "phoneNumber"; FieldIdEnum["postalCode"] = "postalCode"; FieldIdEnum["address1"] = "address1"; FieldIdEnum["city"] = "city"; FieldIdEnum["country"] = "country"; FieldIdEnum["state"] = "state"; FieldIdEnum["dischargeDate"] = "dischargeDate"; FieldIdEnum["docUpload"] = "docUpload"; FieldIdEnum["status"] = "status"; FieldIdEnum["statuses"] = "statuses"; FieldIdEnum["marketConsentValue"] = "marketConsentValue"; FieldIdEnum["socialSecurityNumber"] = "socialSecurityNumber"; FieldIdEnum["carrierConsentValue"] = "carrierConsentValue"; FieldIdEnum["driverLicenseNumber"] = "driverLicenseNumber"; })(FieldIdEnum || (FieldIdEnum = {})); const FieldIds = Object.values(FieldIdEnum); // For runtime checks var HookNameEnum; (function (HookNameEnum) { HookNameEnum["ON_VERIFICATION_READY"] = "ON_VERIFICATION_READY"; HookNameEnum["ON_VERIFICATION_SUCCESS"] = "ON_VERIFICATION_SUCCESS"; HookNameEnum["ON_VERIFICATION_STEP_CHANGE"] = "ON_VERIFICATION_STEP_CHANGE"; })(HookNameEnum || (HookNameEnum = {})); const HookNames = Object.values(HookNameEnum); /** * Add to the list of known locales for more helpful runtime checks. */ const registerAdditionalLocales = (locales) => { logger.info(`Registering additional locales ${locales.join(', ')}`); Locales.push(...locales); }; var StateEnum; (function (StateEnum) { StateEnum["AK"] = "AK"; StateEnum["AL"] = "AL"; StateEnum["AR"] = "AR"; StateEnum["AZ"] = "AZ"; StateEnum["CA"] = "CA"; StateEnum["CO"] = "CO"; StateEnum["CT"] = "CT"; StateEnum["DC"] = "DC"; StateEnum["DE"] = "DE"; StateEnum["FL"] = "FL"; StateEnum["GA"] = "GA"; StateEnum["HI"] = "HI"; StateEnum["IA"] = "IA"; StateEnum["ID"] = "ID"; StateEnum["IL"] = "IL"; StateEnum["IN"] = "IN"; StateEnum["KS"] = "KS"; StateEnum["KY"] = "KY"; StateEnum["LA"] = "LA"; StateEnum["MA"] = "MA"; StateEnum["MD"] = "MD"; StateEnum["ME"] = "ME"; StateEnum["MI"] = "MI"; StateEnum["MN"] = "MN"; StateEnum["MO"] = "MO"; StateEnum["MS"] = "MS"; StateEnum["MT"] = "MT"; StateEnum["NC"] = "NC"; StateEnum["ND"] = "ND"; StateEnum["NE"] = "NE"; StateEnum["NH"] = "NH"; StateEnum["NJ"] = "NJ"; StateEnum["NM"] = "NM"; StateEnum["NV"] = "NV"; StateEnum["NY"] = "NY"; StateEnum["OH"] = "OH"; StateEnum["OK"] = "OK"; StateEnum["OR"] = "OR"; StateEnum["PA"] = "PA"; StateEnum["RI"] = "RI"; StateEnum["SC"] = "SC"; StateEnum["SD"] = "SD"; StateEnum["TN"] = "TN"; StateEnum["TX"] = "TX"; StateEnum["UT"] = "UT"; StateEnum["VA"] = "VA"; StateEnum["VT"] = "VT"; StateEnum["WA"] = "WA"; StateEnum["WI"] = "WI"; StateEnum["WV"] = "WV"; StateEnum["WY"] = "WY"; })(StateEnum || (StateEnum = {})); var toggleSelection = function () { var selection = document.getSelection(); if (!selection.rangeCount) { return function () {}; } var active = document.activeElement; var ranges = []; for (var i = 0; i < selection.rangeCount; i++) { ranges.push(selection.getRangeAt(i)); } switch (active.tagName.toUpperCase()) { // .toUpperCase handles XHTML case 'INPUT': case 'TEXTAREA': active.blur(); break; default: active = null; break; } selection.removeAllRanges(); return function () { selection.type === 'Caret' && selection.removeAllRanges(); if (!selection.rangeCount) { ranges.forEach(function(range) { selection.addRange(range); }); } active && active.focus(); }; }; var clipboardToIE11Formatting = { "text/plain": "Text", "text/html": "Url", "default": "Text" }; var defaultMessage = "Copy to clipboard: #{key}, Enter"; function format(message) { var copyKey = (/mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl") + "+C"; return message.replace(/#{\s*key\s*}/g, copyKey); } function copy(text, options) { var debug, message, reselectPrevious, range, selection, mark, success = false; if (!options) { options = {}; } debug = options.debug || false; try { reselectPrevious = toggleSelection(); range = document.createRange(); selection = document.getSelection(); mark = document.createElement("span"); mark.textContent = text; // reset user styles for span element mark.style.all = "unset"; // prevents scrolling to the end of the page mark.style.position = "fixed"; mark.style.top = 0; mark.style.clip = "rect(0, 0, 0, 0)"; // used to preserve spaces and line breaks mark.style.whiteSpace = "pre"; // do not inherit user-select (it may be `none`) mark.style.webkitUserSelect = "text"; mark.style.MozUserSelect = "text"; mark.style.msUserSelect = "text"; mark.style.userSelect = "text"; mark.addEventListener("copy", function(e) { e.stopPropagation(); if (options.format) { e.preventDefault(); if (typeof e.clipboardData === "undefined") { // IE 11 debug && console.warn("unable to use e.clipboardData"); debug && console.warn("trying IE specific stuff"); window.clipboardData.clearData(); var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting["default"]; window.clipboardData.setData(format, text); } else { // all other browsers e.clipboardData.clearData(); e.clipboardData.setData(options.format, text); } } if (options.onCopy) { e.preventDefault(); options.onCopy(e.clipboardData); } }); document.body.appendChild(mark); range.selectNodeContents(mark); selection.addRange(range); var successful = document.execCommand("copy"); if (!successful) { throw new Error("copy command was unsuccessful"); } success = true; } catch (err) { debug && console.error("unable to copy using execCommand: ", err); debug && console.warn("trying IE specific stuff"); try { window.clipboardData.setData(options.format || "text", text); options.onCopy && options.onCopy(window.clipboardData); success = true; } catch (err) { debug && console.error("unable to copy using clipboardData: ", err); debug && console.error("falling back to prompt"); message = format("message" in options ? options.message : defaultMessage); window.prompt(message, text); } } finally { if (selection) { if (typeof selection.removeRange == "function") { selection.removeRange(range); } else { selection.removeAllRanges(); } } if (mark) { document.body.removeChild(mark); } reselectPrevious(); } return success; } var copyToClipboard = copy; /** * Wrap a button or link with copy-to-clipboard behavior. * * Example Use: <CopyToClipboard textToCopy={htmlSource} notificationText={<FormattedMessage id="copied" />}> <LinkButton ... /> </CopyToClipboard> */ const twoSeconds = 2000; const classNameHidden = 'sid-to-clipboard__notification-text sid-to-clipboard__notification-text--hidden'; const classNameVisible = 'sid-to-clipboard__notification-text sid-to-clipboard__notification-text--visible'; class CopyToClipboard extends React.Component { constructor(props) { super(props); this.doCopy = this.doCopy.bind(this); this.state = { isShowing: false }; if (props.notificationTimeout) { this.notificationTimeout = props.notificationTimeout; } else { this.notificationTimeout = twoSeconds; } } componentWillUnmount() { clearTimeout(this.timeoutRef); } doCopy() { const { textToCopy } = this.props; copyToClipboard(textToCopy); this.setState(() => ({ isShowing: true })); clearTimeout(this.timeoutRef); this.timeoutRef = setTimeout(() => { this.setState(() => ({ isShowing: false })); }, this.notificationTimeout); } render() { const { isShowing } = this.state; const { notificationText, children } = this.props; return (React.createElement("div", { className: "sid-to-clipboard" }, React.createElement("div", { className: `${isShowing ? classNameVisible : classNameHidden}` }, notificationText || 'Copied'), React.createElement("div", { onClick: this.doCopy, onKeyPress: this.doCopy, role: "button", tabIndex: 0, className: "sid-h-link-like sid-to-clipboard__clickable-text sid-link" }, children || 'Copy'))); } } class ResponseTimeLogger { constructor(url) { this.url = url; this.start = Date.now(); } logNow() { // eslint-disable-next-line let result; if (window.NREUM) { result = { api_call: this.url, api_response_time: (Date.now() - this.start), }; window.NREUM.addPageAction('API-calls-timing', result); } else { logger.warn('Off-site logging not available.'); } return result; } } const ensureTrailingSlash = (url) => url.replace(/\/?$/, '/'); const getQueryParamsFromUrl = (url) => { const newUrl = new URL(url || window.location.toString()); return new URLSearchParams(newUrl.search.slice(1)); }; const getVerificationIdFromQueryString = (queryString) => { const verificationIdQueryParameter = 'verificationId'; const queryStringParameters = new URLSearchParams(queryString); const verificationId = queryStringParameters.get(verificationIdQueryParameter); if (typeof verificationId === 'string' && verificationId.length === 0) { return null; } return verificationId; }; const getTrackingIdFromQueryString = (queryString) => { const trackingIdQueryParameter = 'trackingId'; const queryStringParameters = new URLSearchParams(queryString); const trackingId = queryStringParameters.get(trackingIdQueryParameter); if (typeof trackingId === 'string' && trackingId.length === 0) { return null; } return trackingId; }; const getDomainFromUrl = (url) => { let domain = url; try { domain = new URL(url).hostname; } catch (e) { logger.warn(e); } return domain.replace(/(www\.)?/, ''); }; let customValidators = {}; let customValidatorFields = []; const setCustomValidator = (validatorField, newValidator) => { logger.log(`customValidator registering \n${newValidator}\n for custom field '${validatorField}'`); customValidators[validatorField] = newValidator; customValidatorFields.push(validatorField); }; const getCustomValidator = (validatorField) => { if (customValidators[validatorField]) { logger.log(`getCustomValidator returning '${validatorField}'`); return customValidators[validatorField]; } logger.error(`Custom validator for field '${validatorField}' does not exist. Has a custom validator been registered using the setCustomValidator method?`, 'getCustomValidator'); return null; }; const customValidatorExists$1 = (validatorField) => customValidatorFields.indexOf(validatorField) > -1; const removeCustomValidator = (validatorField) => { delete customValidators[validatorField]; const validatorIndex = customValidatorFields.indexOf(validatorField); if (validatorIndex !== -1) { customValidatorFields.splice(validatorIndex, 1); } else { logger.error(`Custom validator for field '${validatorField}' has not been removed.`, 'removeCustomValidator'); } }; const getCustomValidatorFields = () => customValidatorFields; const resetCustomValidators = () => { customValidators = {}; customValidatorFields = []; logger.info('Custom validators have been reset'); }; const assertValidVerificationStepName = (candidate) => { // TODO - only in dev mode if (VerificationSteps.indexOf(candidate) < 0) { throw new Error(`Expected valid verification step name but received "${candidate}".`); } }; const assertValidMockStepName = (candidate) => { // TODO - only in dev mode if (MockSteps.indexOf(candidate) < 0) { throw new Error(`Expected valid verification step name but received "${candidate}".`); } }; const assertValidSegmentName = (candidate) => { // TODO - only in dev mode if (Segments.indexOf(candidate) < 0) { throw new Error(`Expected valid segment name but received "${candidate}".`); } }; const assertValidLocale = (locale) => { if (!(isValidLocale(locale))) { throw new Error(`Invalid locale ${locale}, expected one of ${Locales.join(', ')}`); } }; const isValidLocale = (locale) => Locales.indexOf(locale) > -1; const assertValidHtmlElement = (element) => { if (!(element && element.nodeType === Node.ELEMENT_NODE)) { throw new Error(`Expected argument of type Node.ELEMENT_NODE but received "${typeof element} ${element.nodeType}"`); } }; const assertValidProgramId = (programId) => { assertValidDatabaseId(programId); }; const assertValidFieldId = (candidate) => { const customValidatorFields = getCustomValidatorFields(); if (FieldIds.indexOf(candidate) < 0 && customValidatorFields.indexOf(candidate) < 0) { throw new Error(`Expected valid field ID but received ${candidate}. Valid FieldIds are [${FieldIds.join(', ')}, ${customValidatorFields.join(', ')}]`); } }; const assertValidTryAgainStep = (candidate) => { if (TryAgainSteps.indexOf(candidate) < 0) { throw new Error(`Expected valid try again step but received ${candidate}. Valid TryAgainSteps are [${TryAgainSteps.join(', ')}]`); } }; const assertValidHook = (hook) => { assertValidHookName(hook.name); assertValidFunction(hook.callback); }; const assertValidHookName = (candidate) => { if (HookNames.indexOf(candidate) < 0) { throw new Error(`Expected valid hook name but received ${candidate}. Valid HookNames are [${HookNames.join(', ')}]`); } }; const assertValidFunction = (candidate) => { if (typeof candidate !== 'function') { throw new Error(`Expected type "function", but received ${typeof candidate}`); } }; const assertValidTrackingId = (candidate) => { if (typeof candidate !== 'string') { throw new Error(`Expected trackingId to be a string, but received ${typeof candidate} instead.`); } if (candidate.length < 1) { throw new Error('Expected trackingId string length greather than 0.'); } }; const assertValidConversionRequest = (candidate) => { if (typeof candidate !== 'object') { throw new Error(`Expected conversion request to be an object, but received ${typeof candidate} instead.`); } if (candidate.hasOwnProperty('amount') && typeof candidate.amount !== 'number') { throw new Error('Expected conversion request property "amount" to have type number.'); } }; const assertValidDatabaseId = (candidate) => { const validId = new RegExp('^[0-9a-fA-F]{24}$'); if (!validId.test(candidate)) { throw new Error(`Invalid databaseId "${candidate}". Expected a 24-digit hexadecimal string.`); } }; const DEFAULT_LOCALE = 'en-US'; const DEFAULT_CDN_BASE_URL = 'https://cdn.jsdelivr.net/npm/@sheerid/jslib@1/'; const ACCEPTED_DOC_MIME_TYPES = [ 'image/png', 'image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'application/pdf', ]; const MAX_DOC_UPLOAD_DOCS_ALLOWED = 3; const UPLOAD_FILE_PREFIX = 'file'; const QUERY_STRING_STEP_OVERRIDE = 'mockStep'; const QUERY_STRING_SUBSEGMENT_OVERRIDE = 'mockSubSegment'; const QUERY_STRING_ERRORID_OVERRIDE = 'mockErrorId'; const QUERY_STRING_PREV_STEP_OVERRIDE = 'mockPreviousStep'; const SSN_STRING_LENGTH = 9; const DEFAULT_MINIMUM_ORG_SEARCH_VALUE_LENGTH = 1; const DEFAULT_PRIVACY_POLICY_URL = 'https://www.sheerid.com/privacy-policy/'; const SHEERID = 'SheerID'; const requestOrganizationConstants = { MAX_RESULT_SIZE: 25, ORG_TYPES: 'UNIVERSITY,HIGH_SCHOOL,K12', DEFAULT_ORG_TYPES: 'UNIVERSITY', URL_REGEX: /(https?:\/\/(www\.)?)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/, SCHOOL_HOUSE_URL: 'https://s3.amazonaws.com/com.sheerid.resources/common/images/requestOrganization/school.svg', SHEERID_LOGO_URL: 'https://s3.amazonaws.com/com.sheerid.resources/common/images/requestOrganization/logo.svg', FEEDBACK_FORM_URL: 'https://verify.sheerid.com/verification-support/feedback.html?token=', }; const HTTP_REQUEST_TIMEOUT = 10000; const iframeClassNames = { INLINE_IFRAME_CONTENT: 'sid-inline-iframe', MODAL_WRAPPER: 'sid-modal__wrapper', MODAL_IFRAME: 'sid-modal__iframe', OVERLAY: 'sid-modal__overlay', CLOSE_BUTTON: 'sid-modal__close-button', CLOSE_TEXT: 'sid-modal__close-text', CLOSE_ICON: 'sid-modal__close-icon', }; const iframeConstants = { CLASS_NAMES: iframeClassNames, DEFAULT_MOBILE_THRESHOLD_WIDTH: 620, MODAL_OPACITY_TRANSITION_PERIOD: 300, }; const restOptions = { serviceUrl: 'https://services.sheerid.com/', resources: { verification: 'rest/v2/verification/', program: { base: 'rest/v2/program/', theme: 'theme', organization: 'organization', }, conversion: { base: 'rest/v2/conversion/', }, }, }; const cookieOptions = { enabled: true, secure: true, expires: 7, }; const defaultOptions = { restApi: restOptions, mockStep: undefined, mockSubSegment: undefined, mockErrorId: undefined, doFetchTheme: true, logLevel: 'error', locale: null, messages: {}, messagesWithLocale: {}, urlStudentFaq: 'https://verify.sheerid.com/student-faq/', urlSeniorFaq: 'https://verify.sheerid.com/us-senior-faq/', urlAgeFaq: 'https://verify.sheerid.com/us-age-faq/', urlMilitaryFaq: 'https://verify.sheerid.com/military-faq/', urlTeacherFaq: 'https://verify.sheerid.com/us-teacher-faq/', urlMemberFaq: 'https://verify.sheerid.com/membership-faq/', urlFirstResponderFaq: 'https://verify.sheerid.com/first-responder-faq/', urlMedicalFaq: 'https://verify.sheerid.com/us-medical-faq/', urlEmploymentFaq: 'https://verify.sheerid.com/employment-faq/', urlIdentityFaq: 'https://verify.sheerid.com/identity-faq/', urlLicensedProfessionalFaq: 'https://verify.sheerid.com/licensed-professional-faq/', urlAddSchoolFaq: 'https://verify.sheerid.com/add-school-request-faq/', urlAddSchoolForm: 'https://offers.sheerid.com/sheerid/add-school-request/', privacyPolicyUrl: undefined, cookies: cookieOptions, useFingerprinting: false, verificationId: undefined, minimumOrganizationSearchLength: DEFAULT_MINIMUM_ORG_SEARCH_VALUE_LENGTH, httpRequestTimeout: HTTP_REQUEST_TIMEOUT, }; let options$1 = { ...defaultOptions }; const getOptions = () => options$1; const resetOptions = () => { options$1 = { ...defaultOptions }; }; const setOptions = (newOptions) => { if (newOptions.hasOwnProperty('logLevel')) { try { logger.setLogLevel(newOptions.logLevel); } catch (e) { console.error(e); } options$1.logLevel = newOptions.logLevel; // keep options in sync with logger } if (newOptions.hasOwnProperty('restApi')) { const restApiOptions = newOptions.restApi; if (restApiOptions.hasOwnProperty('serviceUrl')) { const newUrl = ensureTrailingSlash(newOptions.restApi.serviceUrl); options$1.restApi.serviceUrl = newUrl; logger.info(`option "serviceUrl" set to ${options$1.restApi.serviceUrl}`); } } if (newOptions.hasOwnProperty(QUERY_STRING_STEP_OVERRIDE)) { assertValidMockStepName(newOptions[QUERY_STRING_STEP_OVERRIDE]); options$1[QUERY_STRING_STEP_OVERRIDE] = newOptions[QUERY_STRING_STEP_OVERRIDE]; logger.info(`option "${QUERY_STRING_STEP_OVERRIDE}" set to ${options$1[QUERY_STRING_STEP_OVERRIDE]}`); } if (newOptions.hasOwnProperty(QUERY_STRING_PREV_STEP_OVERRIDE)) { assertValidMockStepName(newOptions[QUERY_STRING_STEP_OVERRIDE]); options$1[QUERY_STRING_PREV_STEP_OVERRIDE] = newOptions[QUERY_STRING_PREV_STEP_OVERRIDE]; logger.info(`option "${QUERY_STRING_PREV_STEP_OVERRIDE}" set to ${options$1[QUERY_STRING_PREV_STEP_OVERRIDE]}`); } if (newOptions.hasOwnProperty(QUERY_STRING_SUBSEGMENT_OVERRIDE)) { options$1[QUERY_STRING_SUBSEGMENT_OVERRIDE] = newOptions[QUERY_STRING_SUBSEGMENT_OVERRIDE]; logger.info(`option "${QUERY_STRING_SUBSEGMENT_OVERRIDE}" set to ${options$1[QUERY_STRING_SUBSEGMENT_OVERRIDE]}`); } if (newOptions.hasOwnProperty(QUERY_STRING_ERRORID_OVERRIDE)) { options$1[QUERY_STRING_ERRORID_OVERRIDE] = newOptions[QUERY_STRING_ERRORID_OVERRIDE]; logger.info(`option "${QUERY_STRING_ERRORID_OVERRIDE}" set to ${options$1[QUERY_STRING_ERRORID_OVERRIDE]}`); } if (newOptions.hasOwnProperty('messages')) { options$1.messagesWithLocale = { ...options$1.messagesWithLocale, 'en-US': newOptions.messages }; logger.warn('option "messages" has been deprecated and replaced with "messagesWithLocale". Messages have been set for locale "en-US" using: ', options$1.messagesWithLocale, '\nThese messages will override existing messages of the same key for "en-US" locale.'); } if (newOptions.hasOwnProperty('messagesWithLocale')) { options$1.messagesWithLocale = deepMerge({}, options$1.messagesWithLocale, newOptions.messagesWithLocale); if (newOptions && newOptions.messagesWithLocale) { registerAdditionalLocales(Object.keys(newOptions.messagesWithLocale)); } logger.info('option "messagesWithLocale" set to', options$1.messagesWithLocale); } if (newOptions.hasOwnProperty('locale')) { assertValidLocale(newOptions.locale); options$1.locale = newOptions.locale; logger.info(`option "locale" set to ${options$1.locale}`); } if (newOptions.hasOwnProperty('urlStudentFaq')) { // assertValidUrl(newOptions.urlStudentFaq); options$1.urlStudentFaq = newOptions.urlStudentFaq; logger.info(`option "urlStudentFaq" set to ${options$1.urlStudentFaq}`); } if (newOptions.hasOwnProperty('urlSeniorFaq')) { // assertValidUrl(newOptions.urlSeniorFaq); options$1.urlSeniorFaq = newOptions.urlSeniorFaq; logger.info(`option "urlSeniorFaq" set to ${options$1.urlSeniorFaq}`); } if (newOptions.hasOwnProperty('urlMilitaryFaq')) { // assertValidUrl(newOptions.urlMilitaryFaq); options$1.urlMilitaryFaq = newOptions.urlMilitaryFaq; logger.info(`option "urlMilitaryFaq" set to ${options$1.urlMilitaryFaq}`); } if (newOptions.hasOwnProperty('urlTeacherFaq')) { // assertValidUrl(newOptions.urlTeacherFaq); options$1.urlTeacherFaq = newOptions.urlTeacherFaq; logger.info(`option "urlTeacherFaq" set to ${options$1.urlTeacherFaq}`); } if (newOptions.hasOwnProperty('urlMemberFaq')) { // assertValidUrl(newOptions.urlMemberFaq); options$1.urlMemberFaq = newOptions.urlMemberFaq; logger.info(`option "urlMemberFaq" set to ${options$1.urlMemberFaq}`); } if (newOptions.hasOwnProperty('urlMedicalFaq')) { options$1.urlMedicalFaq = newOptions.urlMedicalFaq; logger.info(`option "urlMedicalFaq" set to ${options$1.urlMedicalFaq}`); } if (newOptions.hasOwnProperty('urlEmploymentFaq')) { options$1.urlEmploymentFaq = newOptions.urlEmploymentFaq; logger.info(`option "urlEmploymentFaq" set to ${options$1.urlEmploymentFaq}`); } if (newOptions.hasOwnProperty('urlAddSchoolFaq')) { options$1.urlAddSchoolFaq = newOptions.urlAddSchoolFaq; logger.info(`option "urlAddSchoolFaq" set to ${options$1.urlAddSchoolFaq}`); } if (newOptions.hasOwnProperty('urlAddSchoolForm')) { options$1.urlAddSchoolForm = newOptions.urlAddSchoolForm; logger.info(`option "urlAddSchoolForm" set to ${options$1.urlAddSchoolForm}`); } if (newOptions.hasOwnProperty('doFetchTheme')) { options$1.doFetchTheme = newOptions.doFetchTheme; logger.info(`option "doFetchTheme" set to ${options$1.doFetchTheme}`); } if (newOptions.hasOwnProperty('cookies')) { options$1.cookies = { ...options$1.cookies, ...newOptions.cookies }; logger.info('option "cookies" set to', options$1.cookies); } if (newOptions.hasOwnProperty('useFingerprinting')) { options$1.useFingerprinting = newOptions.useFingerprinting; logger.info('option "useFingerprinting" set to', options$1.useFingerprinting); } if (newOptions.hasOwnProperty('marketConsent')) { options$1.marketConsent = newOptions.marketConsent; logger.info('option "market consent" set to', options$1.marketConsent); } if (newOptions.hasOwnProperty('verificationId')) { options$1.verificationId = newOptions.verificationId; logger.info('option "verificationId" set to', options$1.verificationId); } if (newOptions.hasOwnProperty('minimumOrganizationSearchLength')) { options$1.minimumOrganizationSearchLength = newOptions.minimumOrganizationSearchLength; logger.info('option "minimumOrganizationSearchLength" set to', options$1.minimumOrganizationSearchLength); } if (newOptions.hasOwnProperty('customCss')) { options$1.customCss = newOptions.customCss; logger.info('option "customCss" set to', options$1.customCss); } if (newOptions.hasOwnProperty('logoUrl')) { options$1.logoUrl = newOptions.logoUrl; logger.info('option "logoUrl" set to', options$1.logoUrl); } if (newOptions.hasOwnProperty('httpRequestTimeout')) { options$1.httpRequestTimeout = newOptions.httpRequestTimeout; logger.info('option "httpRequestTimeout" set to', options$1.httpRequestTimeout); } if (newOptions.hasOwnProperty('privacyPolicyUrl')) { options$1.privacyPolicyUrl = newOptions.privacyPolicyUrl; logger.info('option "privacyPolicyUrl" set to', options$1.privacyPolicyUrl); } }; const defaultJsonHeaders = { Accept: 'application/json', 'Content-Type': 'application/json', }; const defaultFileUploadHeaders = { Accept: 'application/json', }; const fetchWithTimeout = (url, options = {}) => { const timeout = getOptions().httpRequestTimeout; return new Promise((resolve, reject) => { const timeoutTimer = setTimeout(() => { const networkErrorId = 'requestTimeout'; reject(new Error(networkErrorId)); }, timeout); return fetch(url, options).then(resolve, (error) => { logger.error(`Failed to fetch ${url}`, error); const networkErrorId = 'failedToFetch'; reject(new Error(networkErrorId)); }) .finally(() => { clearTimeout(timeoutTimer); }); }); }; const PostJson = async (url, body, headers = defaultJsonHeaders) => { const timeLog = new ResponseTimeLogger(url); const response = await fetchWithTimeout(url, { headers, method: 'POST', body: JSON.stringify(body), }); return await processResponse(response, timeLog); }; const DeleteJson = async (url, headers = defaultJsonHeaders) => { const timeLog = new ResponseTimeLogger(url); const response = await fetchWithTimeout(url, { headers, method: 'DELETE', }); return await processResponse(response, timeLog); }; const GetJson = async (url, headers = defaultJsonHeaders) => { const timeLog = new ResponseTimeLogger(url); const response = await fetchWithTimeout(url, { headers, method: 'GET', }); return await processResponse(response, timeLog); }; const GetResponse = async (url, headers = defaultJsonHeaders) => await fetchWithTimeout(url, {