@optionfactory/ful 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/ful.iife.js +73 -57
- package/dist/ful.iife.js.map +1 -1
- package/dist/ful.iife.min.js +1 -1
- package/dist/ful.iife.min.js.map +1 -1
- package/dist/ful.min.mjs +1 -1
- package/dist/ful.min.mjs.map +1 -1
- package/dist/ful.mjs +73 -57
- package/dist/ful.mjs.map +1 -1
- package/package.json +1 -1
package/dist/ful.min.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ful.min.mjs","sources":["../src/bindings.mjs","../src/encodings.mjs","../src/forms.mjs","../src/http-client.mjs","../src/storage.mjs","../src/oauth-authorization-code.mjs","../src/timing.mjs","../src/wizard.mjs","../src/app.mjs"],"sourcesContent":["/* global CSS */\n\nfunction extract(extractors, el) {\n const maybeExtractor = extractors[el.dataset['bindExtractor']] || extractors[el.dataset['bindProvide']];\n if (maybeExtractor) {\n return maybeExtractor(el);\n }\n if (el.getAttribute('type') === 'radio') {\n if (!el.checked) {\n return undefined;\n }\n return el.dataset['bindType'] === 'boolean' ? el.value === 'true' : el.value;\n }\n if (el.getAttribute('type') === 'checkbox') {\n return el.checked;\n }\n if (el.dataset['bindType'] === 'boolean') {\n return !el.value ? null : el.value === 'true';\n }\n return el.value || null;\n}\n\nfunction mutate(mutators, el, raw, key, values) {\n const maybeMutator = mutators[el.dataset['bindMutator']] || mutators[el.dataset['bindProvide']];\n if (maybeMutator) {\n maybeMutator(el, raw, key, values);\n return;\n }\n if (el.getAttribute('type') === 'radio') {\n el.checked = el.getAttribute('value') === raw;\n return;\n }\n if (el.getAttribute('type') === 'checkbox') {\n el.checked = raw;\n return;\n }\n el.value = raw;\n}\n\n\nfunction providePath(result, path, value) {\n const keys = path.split(\".\").map((k) => k.match(/^[0-9]+$/) ? +k : k);\n let current = result;\n let previous = null;\n for (let i = 0; ; ++i) {\n const ckey = keys[i];\n const pkey = keys[i - 1];\n if (Number.isInteger(ckey) && !Array.isArray(current)) {\n if (previous !== null) {\n previous[pkey] = current = [];\n } else {\n result = current = [];\n }\n }\n if (i === keys.length - 1) {\n //when value is undefined we only want to define the property if it's not defined \n current[ckey] = value !== undefined ? value : (ckey in current ? current[ckey] : null);\n return result;\n }\n if (current[ckey] === undefined) {\n current[ckey] = {};\n }\n previous = current;\n current = current[ckey];\n }\n}\n\nclass Bindings {\n\n constructor( {extractors, mutators, ignoredChildrenSelector, valueHoldersSelector}) {\n this.extractors = extractors || {};\n this.mutators = mutators || {};\n this.valueHoldersSelector = valueHoldersSelector || 'input[name], select[name], textarea[name]';\n this.ignoredChildrenSelector = ignoredChildrenSelector || '.d-none';\n }\n setValues(el, values) {\n for (let k in values) {\n if (!values.hasOwnProperty(k)) {\n continue;\n }\n Array.from(el.querySelectorAll(`[name='${CSS.escape(k)}']`)).forEach((el) => {\n mutate(this.mutators, el, values[k], k, values);\n });\n }\n }\n getValues(el) {\n return Array.from(el.querySelectorAll(this.valueHoldersSelector))\n .filter((el) => {\n if (el.dataset['bindInclude'] === 'never') {\n return false;\n }\n return el.dataset['bindInclude'] === 'always' || el.closest(this.ignoredChildrenSelector) === null;\n })\n .reduce((result, el) => {\n return providePath(result, el.getAttribute('name'), extract(this.extractors, el));\n }, {});\n }\n}\n\n\n\nexport { Bindings };","\n\nclass Base64 {\n static encode(arrayBuffer, dialect) {\n const d = dialect || Base64.URL_SAFE;\n const len = arrayBuffer.byteLength;\n const view = new Uint8Array(arrayBuffer);\n let res = '';\n for (let i = 0; i < len; i += 3) {\n const v1 = d[view[i] >> 2];\n const v2 = d[((view[i] & 3) << 4) | (view[i + 1] >> 4)];\n const v3 = d[((view[i + 1] & 15) << 2) | (view[i + 2] >> 6)];\n const v4 = d[view[i + 2] & 63];\n res += v1 + v2 + v3 + v4;\n }\n if (len % 3 === 2) {\n res = res.substring(0, res.length - 1);\n } else if (len % 3 === 1) {\n res = res.substring(0, res.length - 2);\n }\n return res;\n }\n static decode(str, dialect) {\n const d = dialect || Base64.URL_SAFE;\n let nbytes = Math.floor(str.length * 0.75);\n for (let i = 0; i !== str.length; ++i) {\n if (str[str.length - i - 1] !== '=') {\n break;\n }\n --nbytes;\n }\n const view = new Uint8Array(nbytes);\n\n let vi = 0;\n let si = 0;\n while (vi < str.length * 0.75) {\n const v1 = d.indexOf(str.charAt(si++));\n const v2 = d.indexOf(str.charAt(si++));\n const v3 = d.indexOf(str.charAt(si++));\n const v4 = d.indexOf(str.charAt(si++));\n view[vi++] = (v1 << 2) | (v2 >> 4);\n view[vi++] = ((v2 & 15) << 4) | (v3 >> 2);\n view[vi++] = ((v3 & 3) << 6) | v4;\n }\n\n return view.buffer;\n }\n}\n\nBase64.STANDARD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nBase64.URL_SAFE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\nclass Hex {\n static decode(hex) {\n if (hex.length % 2 !== 0) {\n throw new Error(\"invalid length\");\n }\n const lenInBytes = hex.length / 2;\n return new Uint8Array(lenInBytes).map((e, i) => {\n const offset = i * 2;\n const octet = hex.substring(offset, offset + 2);\n return parseInt(octet, 16);\n });\n }\n static encode(bytes, upper) {\n return Array.from(bytes)\n .map(b => b.toString(16))\n .map(b => upper ? b.toUpperCase() : b)\n .map(o => o.padStart(2, 0))\n .join('');\n }\n}\n\nexport { Base64, Hex };","/* global Infinity, CSS */\n\n\nclass Form {\n constructor(el, bindings, {globalErrorsEl, fieldContainerSelector, errorClass, hideClass}) {\n this.el = el;\n this.bindings = bindings;\n this.globalErrorsEl = globalErrorsEl;\n this.fieldContainerSelector = fieldContainerSelector !== undefined ? fieldContainerSelector : Form.DEFAULT_FIELD_CONTAINER_SELECTOR;\n this.errorClass = errorClass || Form.DEFAULT_ERROR_CLASS;\n this.hideClass = hideClass || Form.DEFAULT_HIDE_CLASS;\n }\n setValues(values) {\n return this.bindings.setValues(this.el, values);\n }\n getValues() {\n return this.bindings.getValues(this.el);\n }\n setErrors(errors, scrollFirstErrorIntoView, context) {\n\n this.clearErrors();\n errors\n .map(this.mapError ? this.mapError : (e) => e)\n .filter((e) => e.type === 'FIELD_ERROR' || e.type === 'INVALID_FORMAT')\n .forEach((e) => {\n const name = e.context.replace(\"[\", \".\").replace(\"].\", \".\");\n Array.from(this.el.querySelectorAll(`[name='${CSS.escape(name)}']`))\n .map(el => this.fieldContainerSelector ? el.closest(this.fieldContainerSelector) : el)\n .filter(el => el !== null)\n .forEach(label => {\n label.classList.add(this.errorClass);\n label.dataset['error'] = e.reason;\n });\n });\n if (this.globalErrorsEl) {\n const globalErrors = errors.filter((e) => e.type !== 'FIELD_ERROR' && e.type !== 'INVALID_FORMAT');\n this.globalErrorsEl.innerHTML = globalErrors.map(e => e.reason).join(\"\\n\");\n if (globalErrors.length !== 0) {\n this.globalErrorsEl.classList.remove(this.hideClass);\n }\n }\n if (!scrollFirstErrorIntoView) {\n return;\n }\n const yOffsets = Array.from(this.el.querySelectorAll('.${CSS.escape(this.errorClass)}'))\n .map((label) => label.getBoundingClientRect().y + window.scrollY);\n const firstErrorScrollY = Math.min(...yOffsets);\n if (firstErrorScrollY !== Infinity) {\n window.scroll(window.scrollX, firstErrorScrollY > 100 ? firstErrorScrollY - 100 : 0);\n }\n }\n clearErrors() {\n this.el.querySelectorAll(`.${CSS.escape(this.errorClass)}`).forEach(l => l.classList.remove(this.errorClass));\n if (this.globalErrorsEl) {\n this.globalErrorsEl.innerHTML = '';\n this.globalErrorsEl.classList.add(this.hideClass);\n }\n }\n}\n\nForm.DEFAULT_FIELD_CONTAINER_SELECTOR = 'label';\nForm.DEFAULT_ERROR_CLASS = 'has-error';\nForm.DEFAULT_HIDE_CLASS = 'd-none';\n\n\n/*\n export function forms() {\n }\n \n forms.dropContext = function (context) {\n return function (e) {\n if (e.context && e.context.indexOf(context) === 0) {\n e.context = e.context.substring(context.length);\n }\n return e;\n };\n };\n \n \n Dom.ready(() => {\n document.querySelectorAll('label:not([data-error])').forEach(el => {\n el.dataset['error'] = \"Il valore inserito non è valido\";\n });\n });\n \n Dom.ready(() => {\n Dom.on(document.body, 'change', '[data-pattern]', {}, evt => {\n const el = evt.srcElement;\n const pattern = el.dataset['pattern'];\n const matches = el.value.match(pattern);\n const label = el.closest('label');\n if(label === null){\n return;\n }\n label.classList[matches ? 'remove' : 'add']('has-error'); \n });\n });\n */\nexport { Form };","class ContextInterceptor {\n constructor() {\n const context = document.querySelector(\"meta[name='context']\").getAttribute(\"content\");\n this.context = context.endsWith(\"/\") ? context.substring(0, context.length - 1) : context;\n }\n before(request) {\n const separator = request.resource.startsWith(\"/\") ? \"\" : \"/\";\n request.resource = this.context + separator + request.resource;\n }\n}\n\nclass CsrfTokenInterceptor {\n constructor() {\n this.k = document.querySelector(\"meta[name='_csrf_header']\").getAttribute(\"content\");\n this.v = document.querySelector(\"meta[name='_csrf']\").getAttribute(\"content\");\n }\n before(request) {\n const headers = new Headers(request.options.headers);\n headers.set(this.k, this.v);\n request.options.headers = headers;\n }\n}\n\nclass RedirectOnUnauthorizedInterceptor {\n constructor(redirectUri) {\n this.redirectUri = redirectUri;\n }\n after(request, response) {\n if (response.status !== 401) {\n return;\n }\n window.location.href = redirectUri;\n }\n}\n\nclass Failure extends Error {\n static parseProblems(status, text) {\n const def = [{\n type: \"GENERIC_PROBLEM\",\n context: null,\n reason: `${status}: ${text}`,\n details: null\n }];\n try {\n return text ? JSON.parse(text) : def;\n } catch (e) {\n return def;\n }\n }\n static fromResponse(status, text) {\n return new Failure(status, Failure.parseProblems(status, text));\n }\n constructor(status, problems) {\n super(JSON.stringify(problems));\n this.name = `Failure:${status}`;\n this.status = status;\n this.problems = problems;\n }\n}\n\nclass HttpClientBuilder {\n constructor() {\n this.interceptors = [];\n }\n withContext() {\n this.interceptors.push(new ContextInterceptor());\n return this;\n }\n withCsrfToken() {\n this.interceptors.push(new CsrfTokenInterceptor());\n return this;\n }\n withRedirectOnUnauthorized(redirectUri) {\n this.interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));\n return this;\n }\n withInterceptors(...interceptors) {\n this.interceptors.push(...interceptors);\n return this;\n }\n build() {\n const interceptors = this.interceptors;\n return new HttpClient({interceptors});\n }\n}\n\nclass HttpClient {\n static builder() {\n return new HttpClientBuilder();\n }\n constructor( {interceptors}){\n this.interceptors = interceptors || [];\n }\n async fetch(resource, options) {\n const is = this.interceptors.concat(options.interceptors || []);\n const request = {resource, options};\n await is.forEach(async (i) => {\n if (!i.before) {\n return;\n }\n await i.before(request);\n });\n const response = await fetch(request.resource, request.options);\n await is.forEach(async (i) => {\n if (!i.after) {\n return;\n }\n await i.after(request, response);\n });\n\n return response;\n }\n async json(resource, options) {\n try {\n const response = await this.fetch(resource, options);\n if (!response.ok) {\n const message = await response.text();\n throw Failure.fromResponse(response.status, message);\n }\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } catch (e) {\n if (e instanceof Failure) {\n throw e;\n }\n throw new Failure(0, [{\n type: \"CONNECTION_PROBLEM\",\n context: null,\n reason: e.message,\n details: null\n }]);\n }\n }\n async form(resource, options, uiOptions) {\n const ui = uiOptions || {};\n ui.buttons?.forEach(el => {\n el.setAttribute(\"disabled\", \"disabled\");\n if (ui.loader) {\n el.dataset['oldContent'] = el.innerHTML;\n el.innerHTML = ui.loader;\n }\n });\n try {\n const r = await this.json(resource, options);\n ui.form?.clearErrors();\n return r;\n } catch (e) {\n ui.form?.setErrors(e.problems);\n throw e;\n } finally {\n ui.buttons?.forEach(el => {\n el.removeAttribute(\"disabled\");\n el.innerHTML = el.dataset['oldContent'];\n delete el.dataset['oldContent'];\n });\n }\n }\n}\n\n\n\nexport { HttpClient, Failure };\n","\nclass Storage {\n constructor(prefix, storage) {\n this.prefix = prefix;\n this.storage = storage;\n }\n save(k, v) {\n this.storage.setItem(`${this.prefix}-${k}`, JSON.stringify(v));\n }\n load(k) {\n const got = this.storage.getItem(`${this.prefix}-${k}`);\n return got === undefined ? undefined : JSON.parse(got);\n }\n remove(k) {\n this.storage.removeItem(`${this.prefix}-${k}`);\n }\n pop(k) {\n const decoded = this.load(k);\n this.remove(k);\n return decoded;\n }\n}\n\nclass LocalStorage extends Storage {\n constructor(prefix) {\n super(prefix, localStorage);\n }\n}\n\nclass SessionStorage extends Storage {\n constructor(prefix) {\n super(prefix, sessionStorage);\n }\n}\n\nclass VersionedStorage {\n constructor(storage, key, dataSupplier){\n this.storage = storage;\n this.key = key;\n this.dataSupplier = dataSupplier;\n this.cache = null;\n \n }\n async load(revision){\n const saved = this.storage.load(this.key);\n if (!!saved && saved.revision === revision) {\n this.cache = saved.value;\n return;\n }\n const freshData = await this.dataSupplier(revision, this.key);\n this.storage.save(this.key, {\n revision: revision,\n value: freshData\n });\n this.cache = freshData;\n }\n data(){\n return this.cache;\n }\n}\n\n\n\nexport {LocalStorage, SessionStorage, VersionedStorage};","import { Base64 } from \"./encodings.mjs\";\nimport { SessionStorage } from \"./storage.mjs\";\n\n\nclass AuthorizationCodeFlow {\n static forKeycloak(clientId, realmBaseUrl, redirectUri){\n const authUri = new URL(\"protocol/openid-connect/auth\", realmBaseUrl);\n const tokenUri = new URL(\"protocol/openid-connect/token\", realmBaseUrl);\n const logoutUri = new URL(\"protocol/openid-connect/logout\", realmBaseUrl);\n const scope = \"openid profile\";\n return new AuthorizationCodeFlow(clientId, scope, authUri, tokenUri, logoutUri, redirectUri); \n }\n constructor(clientId, scope, authUri, tokenUri, logoutUri, redirectUri) {\n this.clientId = clientId;\n this.scope = scope;\n this.authUri = authUri;\n this.tokenUri = tokenUri;\n this.logoutUri = logoutUri;\n this.redirectUri = redirectUri;\n this.storage = new SessionStorage(clientId);\n }\n async _auth() {\n const pkceVerifier = Base64.encode(crypto.getRandomValues(new Uint8Array(32)).buffer);\n const pkceChallenge = Base64.encode(await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(pkceVerifier)));\n const state = this.clientId + Base64.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);\n this.storage.save(AuthorizationCodeFlow.PKCE_AND_STATE_KEY, {\n state: state,\n verifier: pkceVerifier\n });\n const url = new URL(this.authUri);\n url.searchParams.set(\"client_id\", this.clientId);\n url.searchParams.set(\"redirect_uri\", this.redirectUri);\n url.searchParams.set(\"response_type\", 'code');\n url.searchParams.set(\"scope\", this.scope);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", pkceChallenge);\n url.searchParams.set(\"code_challenge_method\", 'S256');\n window.location = url;\n }\n async _tokenExchange(code, state) {\n window.history.replaceState('', \"\", this.redirectUri);\n const stateAndVerifier = this.storage.pop(AuthorizationCodeFlow.PKCE_AND_STATE_KEY);\n if (stateAndVerifier.state !== state) {\n throw new Error(\"State mismatch\");\n }\n const response = await fetch(this.tokenUri, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"code\", code],\n [\"grant_type\", \"authorization_code\"],\n [\"code_verifier\", stateAndVerifier.verifier],\n [\"state\", stateAndVerifier.state],\n [\"redirect_uri\", this.redirectUri]\n ])\n });\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\"Error:\" + response.status + \": \" + text);\n }\n const token = await response.json();\n return new AuthorizationCodeFlowSession(this.clientId, token, this.tokenUri, this.logoutUri, this.redirectUri);\n }\n async ensureLoggedIn() {\n const url = new URL(window.location.href);\n const code = url.searchParams.get(\"code\");\n if (code && this.storage.load(AuthorizationCodeFlow.PKCE_AND_STATE_KEY)) {\n //if callback from keycloak and we have our state still stored\n const state = url.searchParams.get(\"state\");\n return await this._tokenExchange(code, state);\n }\n //if not authorized\n await this._auth();\n return null;\n }\n}\nAuthorizationCodeFlow.PKCE_AND_STATE_KEY = \"state-and-verifier\";\n\nclass AuthorizationCodeFlowSession {\n static parseToken(token) {\n const [rawHeader, rawPayload, signature] = token.split(\".\");\n return {\n header: JSON.parse(atob(rawHeader)),\n payload: JSON.parse(atob(rawPayload)),\n signature: signature\n };\n } \n constructor(clientId, token, tokenUri, logoutUri, redirectUri) {\n this.clientId = clientId;\n this.token = token;\n this.tokenUri = tokenUri;\n this.logoutUri = logoutUri;\n this.redirectUri = redirectUri;\n this.accessToken = AuthorizationCodeFlowSession.parseToken(token.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(token.refresh_token);\n this.refreshCallback = null;\n }\n onRefresh(callback) {\n this.refreshCallback = callback;\n }\n async refresh() {\n const response = await fetch(this.tokenUri, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"grant_type\", \"refresh_token\"],\n [\"refresh_token\", this.token.refresh_token]\n ])\n });\n if (!response.ok) {\n throw new Error(\"Error:\" + response.code + \": \" + response.text());\n }\n const token = await response.json();\n this.token = token;\n this.accessToken = this._parseToken(token.access_token);\n this.refreshToken = this._parseToken(token.refresh_token);\n if (this.refreshCallback) {\n this.refreshCallback(this.token, this.accessToken, this.refreshToken);\n }\n }\n shouldBeRefreshed(gracePeriod) {\n const now = new Date().getTime();\n const refreshTokenExpiresAt = this.refreshToken.payload.exp * 1000;\n const expired = now > refreshTokenExpiresAt;\n const shouldRefresh = now - gracePeriod > refreshTokenExpiresAt;\n return !expired && shouldRefresh;\n }\n async refreshIf(gracePeriod) {\n if (!this.shouldBeRefreshed(gracePeriod)) {\n return;\n }\n await this.refresh();\n }\n logout() {\n const url = new URL(this.logoutUri);\n url.searchParams.set(\"post_logout_redirect_uri\", this.redirectUri);\n url.searchParams.set(\"id_token_hint\", this.token.id_token);\n window.location = url;\n }\n\n bearerToken() {\n return `Bearer ${this.token.access_token}`;\n }\n \n interceptor(gracePeriodBefore, gracePeriodAfter){\n return new AuthorizationCodeFlowInterceptor(this, gracePeriodBefore, gracePeriodAfter); \n }\n}\n\nclass AuthorizationCodeFlowInterceptor {\n constructor(session, gracePeriodBefore, gracePeriodAfter) {\n this.session = session;\n this.gracePeriodBefore = gracePeriodBefore || 2000;\n this.gracePeriodAfter = gracePeriodAfter || 30000;\n }\n async before(request) {\n await this.session.refreshIf(this.gracePeriodBefore);\n const headers = new Headers(request.options.headers);\n headers.set(\"Authorization\", this.session.bearerToken());\n return request;\n }\n async after(request, response) {\n await this.session.refreshIf(this.gracePeriodAfter);\n return response;\n }\n}\n\n\nexport {AuthorizationCodeFlow, AuthorizationCodeFlowSession, AuthorizationCodeFlowInterceptor };","\nconst timing = {\n sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n DEBOUNCE_DEFAULT: 0,\n DEBOUNCE_IMMEDIATE: 1,\n debounce(timeoutMs, func, options) {\n let tid = null;\n let args = [];\n let previousTimestamp = 0;\n let opts = options || timing.DEBOUNCE_DEFAULT;\n\n const later = () => {\n const elapsed = new Date().getTime() - previousTimestamp;\n if (timeoutMs > elapsed) {\n tid = setTimeout(later, timeoutMs - elapsed);\n return;\n }\n tid = null;\n if (opts !== timing.DEBOUNCE_IMMEDIATE) {\n func(...args);\n }\n // This check is needed because `func` can recursively invoke `debounced`.\n if (tid === null) {\n args = [];\n }\n };\n\n return function () {\n args = arguments;\n previousTimestamp = new Date().getTime();\n if (tid === null) {\n tid = setTimeout(later, timeoutMs);\n if (opts === timing.DEBOUNCE_IMMEDIATE) {\n func(...args);\n }\n }\n };\n },\n THROTTLE_DEFAULT: 0,\n THROTTLE_NO_LEADING: 1,\n THROTTLE_NO_TRAILING: 2,\n throttle(timeoutMs, func, options) {\n let tid = null;\n let args = [];\n let previousTimestamp = 0;\n let opts = options || timing.THROTTLE_DEFAULT;\n\n const later = () => {\n previousTimestamp = (opts & timing.THROTTLE_NO_LEADING) ? 0 : new Date().getTime();\n tid = null;\n func(...args);\n if (tid === null) {\n args = [];\n }\n };\n\n return function () {\n const now = new Date().getTime();\n if (!previousTimestamp && (opts & timing.THROTTLE_NO_LEADING)) {\n previousTimestamp = now;\n }\n const remaining = timeoutMs - (now - previousTimestamp);\n args = arguments;\n if (remaining <= 0 || remaining > timeoutMs) {\n if (tid !== null) {\n clearTimeout(tid);\n tid = null;\n }\n previousTimestamp = now;\n func(...args);\n if (tid === null) {\n args = [];\n }\n } else if (tid === null && !(opts & timing.THROTTLE_NO_TRAILING)) {\n tid = setTimeout(later, remaining);\n }\n };\n\n }\n};\n\n\nexport { timing };","class Wizard {\n constructor(el) {\n this.el = el;\n this.progress = [...el.children].filter(e => e.matches(\"header,ol,ul\"));\n\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n if (current === undefined && children.length > 0) {\n children[0].classList.add('active');\n }\n });\n if (this.el.querySelector('section.current') === null) {\n const firstSection = this.el.querySelector('section:first-of-type');\n if (firstSection !== null) {\n firstSection.classList.add('current');\n }\n }\n }\n next() {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n current?.nextElementSibling?.classList.add('active');\n });\n const currentSection = this.el.querySelector('section.current');\n currentSection.classList.remove(\"current\");\n currentSection.nextElementSibling.classList.add('current');\n\n this.el.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n\n }\n prev() {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n current?.previousElementSibling?.classList.add('active');\n });\n const currentSection = this.el.querySelector('section.current');\n currentSection.classList.remove(\"current\");\n currentSection.previousElementSibling.classList.add('current');\n this.el.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n }\n moveTo = function (n) {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n p.children[+n]?.classList.add('active');\n });\n const currentSection = this.el.querySelector('section.current');\n currentSection?.classList.remove(\"current\");\n const nthSection = this.el.querySelector(`section:nth-child(${+n})`);\n nthSection.classList.add('current');\n this.el.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n }\n}\n\n\n\n\nexport { Wizard };\n","class App {\n constructor() {\n this.configurers = [];\n this.initializers = [];\n this.handlers = [];\n this.running = false;\n document.addEventListener(\"DOMContentLoaded\", async () => {\n await Promise.all(this.configurers);\n await Promise.all(this.initializers.map(h => Promise.resolve(h())));\n await Promise.all(this.handlers.map(h => Promise.resolve(h())));\n });\n }\n configure(cb) {\n this.configurers.push(Promise.resolve(cb()));\n return this;\n }\n initialize(cb) {\n this.initializers.push(cb);\n return this;\n }\n ready(cb) {\n this.handlers.push(cb);\n return this;\n }\n}\n\nexport { App };\n"],"names":["mutate","mutators","el","raw","key","values","maybeMutator","dataset","getAttribute","value","checked","Bindings","constructor","extractors","ignoredChildrenSelector","valueHoldersSelector","this","setValues","k","hasOwnProperty","Array","from","querySelectorAll","CSS","escape","forEach","getValues","filter","closest","reduce","result","path","keys","split","map","match","current","previous","i","ckey","pkey","Number","isInteger","isArray","length","undefined","providePath","maybeExtractor","extract","Base64","static","arrayBuffer","dialect","d","URL_SAFE","len","byteLength","view","Uint8Array","res","substring","str","nbytes","Math","floor","vi","si","v1","indexOf","charAt","v2","v3","v4","buffer","STANDARD","Hex","hex","Error","lenInBytes","e","offset","octet","parseInt","bytes","upper","b","toString","toUpperCase","o","padStart","join","Form","bindings","globalErrorsEl","fieldContainerSelector","errorClass","hideClass","DEFAULT_FIELD_CONTAINER_SELECTOR","DEFAULT_ERROR_CLASS","DEFAULT_HIDE_CLASS","setErrors","errors","scrollFirstErrorIntoView","context","clearErrors","mapError","type","name","replace","label","classList","add","reason","globalErrors","innerHTML","remove","yOffsets","getBoundingClientRect","y","window","scrollY","firstErrorScrollY","min","Infinity","scroll","scrollX","l","ContextInterceptor","document","querySelector","endsWith","before","request","separator","resource","startsWith","CsrfTokenInterceptor","v","headers","Headers","options","set","RedirectOnUnauthorizedInterceptor","redirectUri","after","response","status","location","href","Failure","text","def","details","JSON","parse","parseProblems","problems","super","stringify","HttpClientBuilder","interceptors","withContext","push","withCsrfToken","withRedirectOnUnauthorized","withInterceptors","build","HttpClient","async","is","concat","fetch","ok","message","fromResponse","uiOptions","ui","buttons","setAttribute","loader","r","json","form","removeAttribute","Storage","prefix","storage","save","setItem","load","got","getItem","removeItem","pop","decoded","LocalStorage","localStorage","SessionStorage","sessionStorage","VersionedStorage","dataSupplier","cache","revision","saved","freshData","data","AuthorizationCodeFlow","clientId","realmBaseUrl","authUri","URL","tokenUri","logoutUri","scope","pkceVerifier","encode","crypto","getRandomValues","pkceChallenge","subtle","digest","TextEncoder","state","PKCE_AND_STATE_KEY","verifier","url","searchParams","code","history","replaceState","stateAndVerifier","method","body","URLSearchParams","token","AuthorizationCodeFlowSession","get","_tokenExchange","_auth","rawHeader","rawPayload","signature","header","atob","payload","accessToken","parseToken","access_token","refreshToken","refresh_token","refreshCallback","onRefresh","callback","_parseToken","shouldBeRefreshed","gracePeriod","now","Date","getTime","refreshTokenExpiresAt","exp","refresh","logout","id_token","bearerToken","interceptor","gracePeriodBefore","gracePeriodAfter","AuthorizationCodeFlowInterceptor","session","refreshIf","timing","sleep","ms","Promise","resolve","setTimeout","DEBOUNCE_DEFAULT","DEBOUNCE_IMMEDIATE","debounce","timeoutMs","func","tid","args","previousTimestamp","opts","later","elapsed","arguments","THROTTLE_DEFAULT","THROTTLE_NO_LEADING","THROTTLE_NO_TRAILING","throttle","remaining","clearTimeout","Wizard","progress","children","matches","p","firstSection","next","nextElementSibling","currentSection","dispatchEvent","CustomEvent","bubbles","cancelable","prev","previousElementSibling","moveTo","n","App","configurers","initializers","handlers","running","addEventListener","all","h","configure","cb","initialize","ready"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ful.min.mjs","sources":["../src/bindings.mjs","../src/encodings.mjs","../src/forms.mjs","../src/http-client.mjs","../src/storage.mjs","../src/oauth-authorization-code.mjs","../src/timing.mjs","../src/wizard.mjs","../src/app.mjs"],"sourcesContent":["/* global CSS */\n\nfunction extract(extractors, el) {\n const maybeExtractor = extractors[el.dataset['bindExtractor']] || extractors[el.dataset['bindProvide']];\n if (maybeExtractor) {\n return maybeExtractor(el);\n }\n if (el.getAttribute('type') === 'radio') {\n if (!el.checked) {\n return undefined;\n }\n return el.dataset['bindType'] === 'boolean' ? el.value === 'true' : el.value;\n }\n if (el.getAttribute('type') === 'checkbox') {\n return el.checked;\n }\n if (el.dataset['bindType'] === 'boolean') {\n return !el.value ? null : el.value === 'true';\n }\n return el.value || null;\n}\n\nfunction mutate(mutators, el, raw, key, values) {\n const maybeMutator = mutators[el.dataset['bindMutator']] || mutators[el.dataset['bindProvide']];\n if (maybeMutator) {\n maybeMutator(el, raw, key, values);\n return;\n }\n if (el.getAttribute('type') === 'radio') {\n el.checked = el.getAttribute('value') === raw;\n return;\n }\n if (el.getAttribute('type') === 'checkbox') {\n el.checked = raw;\n return;\n }\n el.value = raw;\n}\n\n\nfunction providePath(result, path, value) {\n const keys = path.split(\".\").map((k) => k.match(/^[0-9]+$/) ? +k : k);\n let current = result;\n let previous = null;\n for (let i = 0; ; ++i) {\n const ckey = keys[i];\n const pkey = keys[i - 1];\n if (Number.isInteger(ckey) && !Array.isArray(current)) {\n if (previous !== null) {\n previous[pkey] = current = [];\n } else {\n result = current = [];\n }\n }\n if (i === keys.length - 1) {\n //when value is undefined we only want to define the property if it's not defined \n current[ckey] = value !== undefined ? value : (ckey in current ? current[ckey] : null);\n return result;\n }\n if (current[ckey] === undefined) {\n current[ckey] = {};\n }\n previous = current;\n current = current[ckey];\n }\n}\n\nclass Bindings {\n\n constructor( {extractors, mutators, ignoredChildrenSelector, valueHoldersSelector}) {\n this.extractors = extractors || {};\n this.mutators = mutators || {};\n this.valueHoldersSelector = valueHoldersSelector || 'input[name], select[name], textarea[name]';\n this.ignoredChildrenSelector = ignoredChildrenSelector || '.d-none';\n }\n setValues(el, values) {\n for (let k in values) {\n if (!values.hasOwnProperty(k)) {\n continue;\n }\n Array.from(el.querySelectorAll(`[name='${CSS.escape(k)}']`)).forEach((el) => {\n mutate(this.mutators, el, values[k], k, values);\n });\n }\n }\n getValues(el) {\n return Array.from(el.querySelectorAll(this.valueHoldersSelector))\n .filter((el) => {\n if (el.dataset['bindInclude'] === 'never') {\n return false;\n }\n return el.dataset['bindInclude'] === 'always' || el.closest(this.ignoredChildrenSelector) === null;\n })\n .reduce((result, el) => {\n return providePath(result, el.getAttribute('name'), extract(this.extractors, el));\n }, {});\n }\n}\n\n\n\nexport { Bindings };","\n\nclass Base64 {\n static encode(arrayBuffer, dialect) {\n const d = dialect || Base64.URL_SAFE;\n const len = arrayBuffer.byteLength;\n const view = new Uint8Array(arrayBuffer);\n let res = '';\n for (let i = 0; i < len; i += 3) {\n const v1 = d[view[i] >> 2];\n const v2 = d[((view[i] & 3) << 4) | (view[i + 1] >> 4)];\n const v3 = d[((view[i + 1] & 15) << 2) | (view[i + 2] >> 6)];\n const v4 = d[view[i + 2] & 63];\n res += v1 + v2 + v3 + v4;\n }\n if (len % 3 === 2) {\n res = res.substring(0, res.length - 1);\n } else if (len % 3 === 1) {\n res = res.substring(0, res.length - 2);\n }\n return res;\n }\n static decode(str, dialect) {\n const d = dialect || Base64.URL_SAFE;\n let nbytes = Math.floor(str.length * 0.75);\n for (let i = 0; i !== str.length; ++i) {\n if (str[str.length - i - 1] !== '=') {\n break;\n }\n --nbytes;\n }\n const view = new Uint8Array(nbytes);\n\n let vi = 0;\n let si = 0;\n while (vi < str.length * 0.75) {\n const v1 = d.indexOf(str.charAt(si++));\n const v2 = d.indexOf(str.charAt(si++));\n const v3 = d.indexOf(str.charAt(si++));\n const v4 = d.indexOf(str.charAt(si++));\n view[vi++] = (v1 << 2) | (v2 >> 4);\n view[vi++] = ((v2 & 15) << 4) | (v3 >> 2);\n view[vi++] = ((v3 & 3) << 6) | v4;\n }\n\n return view.buffer;\n }\n}\n\nBase64.STANDARD = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nBase64.URL_SAFE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\nclass Hex {\n static decode(hex) {\n if (hex.length % 2 !== 0) {\n throw new Error(\"invalid length\");\n }\n const lenInBytes = hex.length / 2;\n return new Uint8Array(lenInBytes).map((e, i) => {\n const offset = i * 2;\n const octet = hex.substring(offset, offset + 2);\n return parseInt(octet, 16);\n });\n }\n static encode(bytes, upper) {\n return Array.from(bytes)\n .map(b => b.toString(16))\n .map(b => upper ? b.toUpperCase() : b)\n .map(o => o.padStart(2, 0))\n .join('');\n }\n}\n\nexport { Base64, Hex };","/* global Infinity, CSS */\n\n\nclass Form {\n constructor(el, bindings, {globalErrorsEl, fieldContainerSelector, errorClass, hideClass}) {\n this.el = el;\n this.bindings = bindings;\n this.globalErrorsEl = globalErrorsEl;\n this.fieldContainerSelector = fieldContainerSelector !== undefined ? fieldContainerSelector : Form.DEFAULT_FIELD_CONTAINER_SELECTOR;\n this.errorClass = errorClass || Form.DEFAULT_ERROR_CLASS;\n this.hideClass = hideClass || Form.DEFAULT_HIDE_CLASS;\n }\n setValues(values) {\n return this.bindings.setValues(this.el, values);\n }\n getValues() {\n return this.bindings.getValues(this.el);\n }\n setErrors(errors, scrollFirstErrorIntoView, context) {\n\n this.clearErrors();\n errors\n .map(this.mapError ? this.mapError : (e) => e)\n .filter((e) => e.type === 'FIELD_ERROR' || e.type === 'INVALID_FORMAT')\n .forEach((e) => {\n const name = e.context.replace(\"[\", \".\").replace(\"].\", \".\");\n Array.from(this.el.querySelectorAll(`[name='${CSS.escape(name)}']`))\n .map(el => this.fieldContainerSelector ? el.closest(this.fieldContainerSelector) : el)\n .filter(el => el !== null)\n .forEach(label => {\n label.classList.add(this.errorClass);\n label.dataset['error'] = e.reason;\n });\n });\n if (this.globalErrorsEl) {\n const globalErrors = errors.filter((e) => e.type !== 'FIELD_ERROR' && e.type !== 'INVALID_FORMAT');\n this.globalErrorsEl.innerHTML = globalErrors.map(e => e.reason).join(\"\\n\");\n if (globalErrors.length !== 0) {\n this.globalErrorsEl.classList.remove(this.hideClass);\n }\n }\n if (!scrollFirstErrorIntoView) {\n return;\n }\n const yOffsets = Array.from(this.el.querySelectorAll('.${CSS.escape(this.errorClass)}'))\n .map((label) => label.getBoundingClientRect().y + window.scrollY);\n const firstErrorScrollY = Math.min(...yOffsets);\n if (firstErrorScrollY !== Infinity) {\n window.scroll(window.scrollX, firstErrorScrollY > 100 ? firstErrorScrollY - 100 : 0);\n }\n }\n clearErrors() {\n this.el.querySelectorAll(`.${CSS.escape(this.errorClass)}`).forEach(l => l.classList.remove(this.errorClass));\n if (this.globalErrorsEl) {\n this.globalErrorsEl.innerHTML = '';\n this.globalErrorsEl.classList.add(this.hideClass);\n }\n }\n}\n\nForm.DEFAULT_FIELD_CONTAINER_SELECTOR = 'label';\nForm.DEFAULT_ERROR_CLASS = 'has-error';\nForm.DEFAULT_HIDE_CLASS = 'd-none';\n\n\n/*\n export function forms() {\n }\n \n forms.dropContext = function (context) {\n return function (e) {\n if (e.context && e.context.indexOf(context) === 0) {\n e.context = e.context.substring(context.length);\n }\n return e;\n };\n };\n \n \n Dom.ready(() => {\n document.querySelectorAll('label:not([data-error])').forEach(el => {\n el.dataset['error'] = \"Il valore inserito non è valido\";\n });\n });\n \n Dom.ready(() => {\n Dom.on(document.body, 'change', '[data-pattern]', {}, evt => {\n const el = evt.srcElement;\n const pattern = el.dataset['pattern'];\n const matches = el.value.match(pattern);\n const label = el.closest('label');\n if(label === null){\n return;\n }\n label.classList[matches ? 'remove' : 'add']('has-error'); \n });\n });\n */\nexport { Form };","class ContextInterceptor {\n constructor() {\n const context = document.querySelector(\"meta[name='context']\").getAttribute(\"content\");\n this.context = context.endsWith(\"/\") ? context.substring(0, context.length - 1) : context;\n }\n async intercept(request, chain){\n const separator = request.resource.startsWith(\"/\") ? \"\" : \"/\";\n request.resource = this.context + separator + request.resource;\n return await chain.proceed(request);\n }\n}\n\nclass CsrfTokenInterceptor {\n constructor() {\n this.k = document.querySelector(\"meta[name='_csrf_header']\").getAttribute(\"content\");\n this.v = document.querySelector(\"meta[name='_csrf']\").getAttribute(\"content\");\n }\n async intercept(request, chain){\n const headers = new Headers(request.options.headers);\n headers.set(this.k, this.v);\n request.options.headers = headers;\n return await chain.proceed(request);\n }\n}\n\nclass RedirectOnUnauthorizedInterceptor {\n constructor(redirectUri) {\n this.redirectUri = redirectUri;\n }\n async intercept(request, chain){\n const response = await chain.proceed(request);\n if (response.status !== 401) {\n return response;\n }\n window.location.href = redirectUri;\n }\n}\n\nclass Failure extends Error {\n static parseProblems(status, text) {\n const def = [{\n type: \"GENERIC_PROBLEM\",\n context: null,\n reason: `${status}: ${text}`,\n details: null\n }];\n try {\n return text ? JSON.parse(text) : def;\n } catch (e) {\n return def;\n }\n }\n static fromResponse(status, text) {\n return new Failure(status, Failure.parseProblems(status, text));\n }\n constructor(status, problems) {\n super(JSON.stringify(problems));\n this.name = `Failure:${status}`;\n this.status = status;\n this.problems = problems;\n }\n}\n\nclass HttpClientBuilder {\n constructor() {\n this.interceptors = [];\n }\n withContext() {\n this.interceptors.push(new ContextInterceptor());\n return this;\n }\n withCsrfToken() {\n this.interceptors.push(new CsrfTokenInterceptor());\n return this;\n }\n withRedirectOnUnauthorized(redirectUri) {\n this.interceptors.push(new RedirectOnUnauthorizedInterceptor(redirectUri));\n return this;\n }\n withInterceptors(...interceptors) {\n this.interceptors.push(...interceptors);\n return this;\n }\n build() {\n const interceptors = this.interceptors;\n return new HttpClient({interceptors});\n }\n}\n\nclass HttpCall {\n async intercept(request, chain){\n return await fetch(request.resource, request.options);\n } \n}\n\nclass HttpInterceptorChain {\n constructor(interceptors, current){\n this.interceptors = interceptors;\n this.current = current;\n }\n async proceed(request){\n const interceptor = this.interceptors[this.current];\n return await interceptor.intercept(request, new HttpInterceptorChain(this.interceptors, this.current + 1));\n }\n}\n\n\nclass HttpClient {\n static builder() {\n return new HttpClientBuilder();\n }\n constructor({interceptors}){\n this.interceptors = interceptors || [];\n }\n async fetch(resource, options) {\n const interceptors = [...this.interceptors, ...options.interceptors || [], new HttpCall()];\n const chain = new HttpInterceptorChain(interceptors, 0);\n return await chain.proceed({resource, options});\n }\n async json(resource, options) {\n try {\n const response = await this.fetch(resource, options);\n if (!response.ok) {\n const message = await response.text();\n throw Failure.fromResponse(response.status, message);\n }\n const text = await response.text();\n return text ? JSON.parse(text) : undefined;\n } catch (e) {\n if (e instanceof Failure) {\n throw e;\n }\n throw new Failure(0, [{\n type: \"CONNECTION_PROBLEM\",\n context: null,\n reason: e.message,\n details: null\n }]);\n }\n }\n async form(resource, options, uiOptions) {\n const ui = uiOptions || {};\n ui.buttons?.forEach(el => {\n el.setAttribute(\"disabled\", \"disabled\");\n if (ui.loader) {\n el.dataset['oldContent'] = el.innerHTML;\n el.innerHTML = ui.loader;\n }\n });\n try {\n const r = await this.json(resource, options);\n ui.form?.clearErrors();\n return r;\n } catch (e) {\n ui.form?.setErrors(e.problems);\n throw e;\n } finally {\n ui.buttons?.forEach(el => {\n el.removeAttribute(\"disabled\");\n el.innerHTML = el.dataset['oldContent'];\n delete el.dataset['oldContent'];\n });\n }\n }\n}\n\n\n\nexport { HttpClient, Failure };\n","\nclass Storage {\n constructor(prefix, storage) {\n this.prefix = prefix;\n this.storage = storage;\n }\n save(k, v) {\n this.storage.setItem(`${this.prefix}-${k}`, JSON.stringify(v));\n }\n load(k) {\n const got = this.storage.getItem(`${this.prefix}-${k}`);\n return got === undefined ? undefined : JSON.parse(got);\n }\n remove(k) {\n this.storage.removeItem(`${this.prefix}-${k}`);\n }\n pop(k) {\n const decoded = this.load(k);\n this.remove(k);\n return decoded;\n }\n}\n\nclass LocalStorage extends Storage {\n constructor(prefix) {\n super(prefix, localStorage);\n }\n}\n\nclass SessionStorage extends Storage {\n constructor(prefix) {\n super(prefix, sessionStorage);\n }\n}\n\nclass VersionedStorage {\n constructor(storage, key, dataSupplier){\n this.storage = storage;\n this.key = key;\n this.dataSupplier = dataSupplier;\n this.cache = null;\n \n }\n async load(revision){\n const saved = this.storage.load(this.key);\n if (!!saved && saved.revision === revision) {\n this.cache = saved.value;\n return;\n }\n const freshData = await this.dataSupplier(revision, this.key);\n this.storage.save(this.key, {\n revision: revision,\n value: freshData\n });\n this.cache = freshData;\n }\n data(){\n return this.cache;\n }\n}\n\n\n\nexport {LocalStorage, SessionStorage, VersionedStorage};","import { Base64 } from \"./encodings.mjs\";\nimport { SessionStorage } from \"./storage.mjs\";\n\n\nclass AuthorizationCodeFlow {\n static forKeycloak(clientId, realmBaseUrl, redirectUri){\n const scope = \"openid profile\";\n return new AuthorizationCodeFlow(clientId, scope, {\n auth: new URL(\"protocol/openid-connect/auth\", realmBaseUrl),\n token: new URL(\"protocol/openid-connect/token\", realmBaseUrl),\n logout: new URL(\"protocol/openid-connect/logout\", realmBaseUrl),\n registration: new URL(\"protocol/openid-connect/registrations\", realmBaseUrl),\n redirect: redirectUri\n }); \n }\n constructor(clientId, scope, {auth, token, registration, logout, redirect}) {\n this.storage = new SessionStorage(clientId);\n this.clientId = clientId;\n this.scope = scope;\n this.uri = {auth, token, registration, logout, redirect};\n }\n async action(uri, additionalParams){\n const pkceVerifier = Base64.encode(crypto.getRandomValues(new Uint8Array(32)).buffer);\n const pkceChallenge = Base64.encode(await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(pkceVerifier)));\n const state = this.clientId + Base64.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);\n this.storage.save(AuthorizationCodeFlow.PKCE_AND_STATE_KEY, {\n state: state,\n verifier: pkceVerifier\n });\n const url = new URL(uri);\n url.searchParams.set(\"client_id\", this.clientId);\n url.searchParams.set(\"redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"response_type\", 'code');\n url.searchParams.set(\"scope\", this.scope);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", pkceChallenge);\n url.searchParams.set(\"code_challenge_method\", 'S256');\n Object.entries(additionalParams || {}).forEach(kv => {\n url.searchParams.set(kv[0], kv[1]);\n });\n window.location = url;\n }\n async registration(additionalParams){\n await this.action(this.uri.registration, additionalParams);\n }\n async applicationInitiatedAction(kcAction){\n await this.action(this.uri.auth, {\n kc_action: kcAction\n });\n }\n async _tokenExchange(code, state) {\n window.history.replaceState('', \"\", this.uri.redirect);\n const stateAndVerifier = this.storage.pop(AuthorizationCodeFlow.PKCE_AND_STATE_KEY);\n if (stateAndVerifier.state !== state) {\n throw new Error(\"State mismatch\");\n }\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"code\", code],\n [\"grant_type\", \"authorization_code\"],\n [\"code_verifier\", stateAndVerifier.verifier],\n [\"state\", stateAndVerifier.state],\n [\"redirect_uri\", this.uri.redirect]\n ])\n });\n if (!response.ok) {\n const text = await response.text();\n throw new Error(\"Error:\" + response.status + \": \" + text);\n }\n const token = await response.json();\n return new AuthorizationCodeFlowSession(this.clientId, token, this.uri);\n }\n async ensureLoggedIn() {\n const url = new URL(window.location.href);\n const code = url.searchParams.get(\"code\");\n if (code && this.storage.load(AuthorizationCodeFlow.PKCE_AND_STATE_KEY)) {\n //if callback from keycloak and we have our state still stored\n const state = url.searchParams.get(\"state\");\n return await this._tokenExchange(code, state);\n }\n //if not authorized\n await this.action(this.uri.auth, {});\n return null;\n }\n}\nAuthorizationCodeFlow.PKCE_AND_STATE_KEY = \"state-and-verifier\";\n\nclass AuthorizationCodeFlowSession {\n static parseToken(token) {\n const [rawHeader, rawPayload, signature] = token.split(\".\");\n const ut8decoder = new TextDecoder(\"utf-8\");\n return {\n header: JSON.parse(ut8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),\n payload: JSON.parse(ut8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),\n signature: signature\n };\n } \n constructor(clientId, t, {token, logout, redirect}) {\n this.clientId = clientId;\n this.token = t;\n this.accessToken = AuthorizationCodeFlowSession.parseToken(t.access_token);\n this.refreshToken = AuthorizationCodeFlowSession.parseToken(t.refresh_token);\n this.uri = { token, logout, redirect }\n this.refreshCallback = null;\n }\n onRefresh(callback) {\n this.refreshCallback = callback;\n }\n async refresh() {\n const response = await fetch(this.uri.token, {\n method: \"POST\",\n headers: {\n \"Content-Type\": 'application/x-www-form-urlencoded'\n },\n body: new URLSearchParams([\n [\"client_id\", this.clientId],\n [\"grant_type\", \"refresh_token\"],\n [\"refresh_token\", this.token.refresh_token]\n ])\n });\n if (!response.ok) {\n throw new Error(\"Error:\" + response.code + \": \" + response.text());\n }\n const token = await response.json();\n this.token = token;\n this.accessToken = this._parseToken(token.access_token);\n this.refreshToken = this._parseToken(token.refresh_token);\n if (this.refreshCallback) {\n this.refreshCallback(this.token, this.accessToken, this.refreshToken);\n }\n }\n shouldBeRefreshed(gracePeriod) {\n const now = new Date().getTime();\n const refreshTokenExpiresAt = this.refreshToken.payload.exp * 1000;\n const expired = now > refreshTokenExpiresAt;\n const shouldRefresh = now - gracePeriod > refreshTokenExpiresAt;\n return !expired && shouldRefresh;\n }\n async refreshIf(gracePeriod) {\n if (!this.shouldBeRefreshed(gracePeriod)) {\n return;\n }\n await this.refresh();\n }\n logout() {\n const url = new URL(this.uri.logout);\n url.searchParams.set(\"post_logout_redirect_uri\", this.uri.redirect);\n url.searchParams.set(\"id_token_hint\", this.token.id_token);\n window.location = url;\n }\n\n bearerToken() {\n return `Bearer ${this.token.access_token}`;\n }\n \n interceptor(gracePeriodBefore, gracePeriodAfter){\n return new AuthorizationCodeFlowInterceptor(this, gracePeriodBefore, gracePeriodAfter); \n }\n}\n\nclass AuthorizationCodeFlowInterceptor {\n constructor(session, gracePeriodBefore, gracePeriodAfter) {\n this.session = session;\n this.gracePeriodBefore = gracePeriodBefore || 2000;\n this.gracePeriodAfter = gracePeriodAfter || 30000;\n }\n async intercept(request, chain) {\n await this.session.refreshIf(this.gracePeriodBefore);\n const headers = new Headers(request.options.headers);\n headers.set(\"Authorization\", this.session.bearerToken());\n request.options.headers = headers;\n const response = await chain.proceed(request);\n await this.session.refreshIf(this.gracePeriodAfter);\n return response;\n }\n}\n\n\nexport {AuthorizationCodeFlow, AuthorizationCodeFlowSession, AuthorizationCodeFlowInterceptor };","\nconst timing = {\n sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n },\n DEBOUNCE_DEFAULT: 0,\n DEBOUNCE_IMMEDIATE: 1,\n debounce(timeoutMs, func, options) {\n let tid = null;\n let args = [];\n let previousTimestamp = 0;\n let opts = options || timing.DEBOUNCE_DEFAULT;\n\n const later = () => {\n const elapsed = new Date().getTime() - previousTimestamp;\n if (timeoutMs > elapsed) {\n tid = setTimeout(later, timeoutMs - elapsed);\n return;\n }\n tid = null;\n if (opts !== timing.DEBOUNCE_IMMEDIATE) {\n func(...args);\n }\n // This check is needed because `func` can recursively invoke `debounced`.\n if (tid === null) {\n args = [];\n }\n };\n\n return function () {\n args = arguments;\n previousTimestamp = new Date().getTime();\n if (tid === null) {\n tid = setTimeout(later, timeoutMs);\n if (opts === timing.DEBOUNCE_IMMEDIATE) {\n func(...args);\n }\n }\n };\n },\n THROTTLE_DEFAULT: 0,\n THROTTLE_NO_LEADING: 1,\n THROTTLE_NO_TRAILING: 2,\n throttle(timeoutMs, func, options) {\n let tid = null;\n let args = [];\n let previousTimestamp = 0;\n let opts = options || timing.THROTTLE_DEFAULT;\n\n const later = () => {\n previousTimestamp = (opts & timing.THROTTLE_NO_LEADING) ? 0 : new Date().getTime();\n tid = null;\n func(...args);\n if (tid === null) {\n args = [];\n }\n };\n\n return function () {\n const now = new Date().getTime();\n if (!previousTimestamp && (opts & timing.THROTTLE_NO_LEADING)) {\n previousTimestamp = now;\n }\n const remaining = timeoutMs - (now - previousTimestamp);\n args = arguments;\n if (remaining <= 0 || remaining > timeoutMs) {\n if (tid !== null) {\n clearTimeout(tid);\n tid = null;\n }\n previousTimestamp = now;\n func(...args);\n if (tid === null) {\n args = [];\n }\n } else if (tid === null && !(opts & timing.THROTTLE_NO_TRAILING)) {\n tid = setTimeout(later, remaining);\n }\n };\n\n }\n};\n\n\nexport { timing };","class Wizard {\n constructor(el) {\n this.el = el;\n this.progress = [...el.children].filter(e => e.matches(\"header,ol,ul\"));\n\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n if (current === undefined && children.length > 0) {\n children[0].classList.add('active');\n }\n });\n if (this.el.querySelector('section.current') === null) {\n const firstSection = this.el.querySelector('section:first-of-type');\n if (firstSection !== null) {\n firstSection.classList.add('current');\n }\n }\n }\n next() {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n current?.nextElementSibling?.classList.add('active');\n });\n const currentSection = this.el.querySelector('section.current');\n currentSection.classList.remove(\"current\");\n currentSection.nextElementSibling.classList.add('current');\n\n this.el.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n\n }\n prev() {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n current?.previousElementSibling?.classList.add('active');\n });\n const currentSection = this.el.querySelector('section.current');\n currentSection.classList.remove(\"current\");\n currentSection.previousElementSibling.classList.add('current');\n this.el.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n }\n moveTo = function (n) {\n this.progress.forEach(p => {\n const children = [...p.children];\n const current = children.filter(e => e.matches(\".active\"))[0];\n current?.classList.remove('active');\n p.children[+n]?.classList.add('active');\n });\n const currentSection = this.el.querySelector('section.current');\n currentSection?.classList.remove(\"current\");\n const nthSection = this.el.querySelector(`section:nth-child(${+n})`);\n nthSection.classList.add('current');\n this.el.dispatchEvent(new CustomEvent('wizard:activate', {\n bubbles: true,\n cancelable: true\n }));\n }\n}\n\n\n\n\nexport { Wizard };\n","class App {\n constructor() {\n this.configurers = [];\n this.initializers = [];\n this.handlers = [];\n this.running = false;\n document.addEventListener(\"DOMContentLoaded\", async () => {\n await Promise.all(this.configurers);\n await Promise.all(this.initializers.map(h => Promise.resolve(h())));\n await Promise.all(this.handlers.map(h => Promise.resolve(h())));\n });\n }\n configure(cb) {\n this.configurers.push(Promise.resolve(cb()));\n return this;\n }\n initialize(cb) {\n this.initializers.push(cb);\n return this;\n }\n ready(cb) {\n this.handlers.push(cb);\n return this;\n }\n}\n\nexport { App };\n"],"names":["mutate","mutators","el","raw","key","values","maybeMutator","dataset","getAttribute","value","checked","Bindings","constructor","extractors","ignoredChildrenSelector","valueHoldersSelector","this","setValues","k","hasOwnProperty","Array","from","querySelectorAll","CSS","escape","forEach","getValues","filter","closest","reduce","result","path","keys","split","map","match","current","previous","i","ckey","pkey","Number","isInteger","isArray","length","undefined","providePath","maybeExtractor","extract","Base64","static","arrayBuffer","dialect","d","URL_SAFE","len","byteLength","view","Uint8Array","res","substring","str","nbytes","Math","floor","vi","si","v1","indexOf","charAt","v2","v3","v4","buffer","STANDARD","Hex","hex","Error","lenInBytes","e","offset","octet","parseInt","bytes","upper","b","toString","toUpperCase","o","padStart","join","Form","bindings","globalErrorsEl","fieldContainerSelector","errorClass","hideClass","DEFAULT_FIELD_CONTAINER_SELECTOR","DEFAULT_ERROR_CLASS","DEFAULT_HIDE_CLASS","setErrors","errors","scrollFirstErrorIntoView","context","clearErrors","mapError","type","name","replace","label","classList","add","reason","globalErrors","innerHTML","remove","yOffsets","getBoundingClientRect","y","window","scrollY","firstErrorScrollY","min","Infinity","scroll","scrollX","l","ContextInterceptor","document","querySelector","endsWith","async","request","chain","separator","resource","startsWith","proceed","CsrfTokenInterceptor","v","headers","Headers","options","set","RedirectOnUnauthorizedInterceptor","redirectUri","response","status","location","href","Failure","text","def","details","JSON","parse","parseProblems","problems","super","stringify","HttpClientBuilder","interceptors","withContext","push","withCsrfToken","withRedirectOnUnauthorized","withInterceptors","build","HttpClient","HttpCall","fetch","HttpInterceptorChain","interceptor","intercept","ok","message","fromResponse","uiOptions","ui","buttons","setAttribute","loader","r","json","form","removeAttribute","Storage","prefix","storage","save","setItem","load","got","getItem","removeItem","pop","decoded","LocalStorage","localStorage","SessionStorage","sessionStorage","VersionedStorage","dataSupplier","cache","revision","saved","freshData","data","AuthorizationCodeFlow","clientId","realmBaseUrl","auth","URL","token","logout","registration","redirect","scope","uri","additionalParams","pkceVerifier","encode","crypto","getRandomValues","pkceChallenge","subtle","digest","TextEncoder","state","PKCE_AND_STATE_KEY","verifier","url","searchParams","Object","entries","kv","action","kcAction","kc_action","code","history","replaceState","stateAndVerifier","method","body","URLSearchParams","AuthorizationCodeFlowSession","get","_tokenExchange","rawHeader","rawPayload","signature","ut8decoder","TextDecoder","header","decode","payload","t","accessToken","parseToken","access_token","refreshToken","refresh_token","refreshCallback","onRefresh","callback","_parseToken","shouldBeRefreshed","gracePeriod","now","Date","getTime","refreshTokenExpiresAt","exp","refresh","id_token","bearerToken","gracePeriodBefore","gracePeriodAfter","AuthorizationCodeFlowInterceptor","session","refreshIf","timing","sleep","ms","Promise","resolve","setTimeout","DEBOUNCE_DEFAULT","DEBOUNCE_IMMEDIATE","debounce","timeoutMs","func","tid","args","previousTimestamp","opts","later","elapsed","arguments","THROTTLE_DEFAULT","THROTTLE_NO_LEADING","THROTTLE_NO_TRAILING","throttle","remaining","clearTimeout","Wizard","progress","children","matches","p","firstSection","next","nextElementSibling","currentSection","dispatchEvent","CustomEvent","bubbles","cancelable","prev","previousElementSibling","moveTo","n","App","configurers","initializers","handlers","running","addEventListener","all","h","configure","cb","initialize","ready"],"mappings":"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"}
|
package/dist/ful.mjs
CHANGED
|
@@ -238,9 +238,10 @@ class ContextInterceptor {
|
|
|
238
238
|
const context = document.querySelector("meta[name='context']").getAttribute("content");
|
|
239
239
|
this.context = context.endsWith("/") ? context.substring(0, context.length - 1) : context;
|
|
240
240
|
}
|
|
241
|
-
|
|
241
|
+
async intercept(request, chain){
|
|
242
242
|
const separator = request.resource.startsWith("/") ? "" : "/";
|
|
243
243
|
request.resource = this.context + separator + request.resource;
|
|
244
|
+
return await chain.proceed(request);
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
247
|
|
|
@@ -249,10 +250,11 @@ class CsrfTokenInterceptor {
|
|
|
249
250
|
this.k = document.querySelector("meta[name='_csrf_header']").getAttribute("content");
|
|
250
251
|
this.v = document.querySelector("meta[name='_csrf']").getAttribute("content");
|
|
251
252
|
}
|
|
252
|
-
|
|
253
|
+
async intercept(request, chain){
|
|
253
254
|
const headers = new Headers(request.options.headers);
|
|
254
255
|
headers.set(this.k, this.v);
|
|
255
256
|
request.options.headers = headers;
|
|
257
|
+
return await chain.proceed(request);
|
|
256
258
|
}
|
|
257
259
|
}
|
|
258
260
|
|
|
@@ -260,9 +262,10 @@ class RedirectOnUnauthorizedInterceptor {
|
|
|
260
262
|
constructor(redirectUri) {
|
|
261
263
|
this.redirectUri = redirectUri;
|
|
262
264
|
}
|
|
263
|
-
|
|
265
|
+
async intercept(request, chain){
|
|
266
|
+
const response = await chain.proceed(request);
|
|
264
267
|
if (response.status !== 401) {
|
|
265
|
-
return;
|
|
268
|
+
return response;
|
|
266
269
|
}
|
|
267
270
|
window.location.href = redirectUri;
|
|
268
271
|
}
|
|
@@ -319,31 +322,35 @@ class HttpClientBuilder {
|
|
|
319
322
|
}
|
|
320
323
|
}
|
|
321
324
|
|
|
325
|
+
class HttpCall {
|
|
326
|
+
async intercept(request, chain){
|
|
327
|
+
return await fetch(request.resource, request.options);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
class HttpInterceptorChain {
|
|
332
|
+
constructor(interceptors, current){
|
|
333
|
+
this.interceptors = interceptors;
|
|
334
|
+
this.current = current;
|
|
335
|
+
}
|
|
336
|
+
async proceed(request){
|
|
337
|
+
const interceptor = this.interceptors[this.current];
|
|
338
|
+
return await interceptor.intercept(request, new HttpInterceptorChain(this.interceptors, this.current + 1));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
|
|
322
343
|
class HttpClient {
|
|
323
344
|
static builder() {
|
|
324
345
|
return new HttpClientBuilder();
|
|
325
346
|
}
|
|
326
|
-
constructor(
|
|
347
|
+
constructor({interceptors}){
|
|
327
348
|
this.interceptors = interceptors || [];
|
|
328
349
|
}
|
|
329
350
|
async fetch(resource, options) {
|
|
330
|
-
const
|
|
331
|
-
const
|
|
332
|
-
await
|
|
333
|
-
if (!i.before) {
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
await i.before(request);
|
|
337
|
-
});
|
|
338
|
-
const response = await fetch(request.resource, request.options);
|
|
339
|
-
await is.forEach(async (i) => {
|
|
340
|
-
if (!i.after) {
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
await i.after(request, response);
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
return response;
|
|
351
|
+
const interceptors = [...this.interceptors, ...options.interceptors || [], new HttpCall()];
|
|
352
|
+
const chain = new HttpInterceptorChain(interceptors, 0);
|
|
353
|
+
return await chain.proceed({resource, options});
|
|
347
354
|
}
|
|
348
355
|
async json(resource, options) {
|
|
349
356
|
try {
|
|
@@ -454,22 +461,22 @@ class VersionedStorage {
|
|
|
454
461
|
|
|
455
462
|
class AuthorizationCodeFlow {
|
|
456
463
|
static forKeycloak(clientId, realmBaseUrl, redirectUri){
|
|
457
|
-
const authUri = new URL("protocol/openid-connect/auth", realmBaseUrl);
|
|
458
|
-
const tokenUri = new URL("protocol/openid-connect/token", realmBaseUrl);
|
|
459
|
-
const logoutUri = new URL("protocol/openid-connect/logout", realmBaseUrl);
|
|
460
464
|
const scope = "openid profile";
|
|
461
|
-
return new AuthorizationCodeFlow(clientId, scope,
|
|
462
|
-
|
|
463
|
-
|
|
465
|
+
return new AuthorizationCodeFlow(clientId, scope, {
|
|
466
|
+
auth: new URL("protocol/openid-connect/auth", realmBaseUrl),
|
|
467
|
+
token: new URL("protocol/openid-connect/token", realmBaseUrl),
|
|
468
|
+
logout: new URL("protocol/openid-connect/logout", realmBaseUrl),
|
|
469
|
+
registration: new URL("protocol/openid-connect/registrations", realmBaseUrl),
|
|
470
|
+
redirect: redirectUri
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
constructor(clientId, scope, {auth, token, registration, logout, redirect}) {
|
|
474
|
+
this.storage = new SessionStorage(clientId);
|
|
464
475
|
this.clientId = clientId;
|
|
465
476
|
this.scope = scope;
|
|
466
|
-
this.
|
|
467
|
-
this.tokenUri = tokenUri;
|
|
468
|
-
this.logoutUri = logoutUri;
|
|
469
|
-
this.redirectUri = redirectUri;
|
|
470
|
-
this.storage = new SessionStorage(clientId);
|
|
477
|
+
this.uri = {auth, token, registration, logout, redirect};
|
|
471
478
|
}
|
|
472
|
-
async
|
|
479
|
+
async action(uri, additionalParams){
|
|
473
480
|
const pkceVerifier = Base64.encode(crypto.getRandomValues(new Uint8Array(32)).buffer);
|
|
474
481
|
const pkceChallenge = Base64.encode(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(pkceVerifier)));
|
|
475
482
|
const state = this.clientId + Base64.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);
|
|
@@ -477,23 +484,34 @@ class AuthorizationCodeFlow {
|
|
|
477
484
|
state: state,
|
|
478
485
|
verifier: pkceVerifier
|
|
479
486
|
});
|
|
480
|
-
const url = new URL(
|
|
487
|
+
const url = new URL(uri);
|
|
481
488
|
url.searchParams.set("client_id", this.clientId);
|
|
482
|
-
url.searchParams.set("redirect_uri", this.
|
|
489
|
+
url.searchParams.set("redirect_uri", this.uri.redirect);
|
|
483
490
|
url.searchParams.set("response_type", 'code');
|
|
484
491
|
url.searchParams.set("scope", this.scope);
|
|
485
492
|
url.searchParams.set("state", state);
|
|
486
493
|
url.searchParams.set("code_challenge", pkceChallenge);
|
|
487
494
|
url.searchParams.set("code_challenge_method", 'S256');
|
|
495
|
+
Object.entries(additionalParams || {}).forEach(kv => {
|
|
496
|
+
url.searchParams.set(kv[0], kv[1]);
|
|
497
|
+
});
|
|
488
498
|
window.location = url;
|
|
489
499
|
}
|
|
500
|
+
async registration(additionalParams){
|
|
501
|
+
await this.action(this.uri.registration, additionalParams);
|
|
502
|
+
}
|
|
503
|
+
async applicationInitiatedAction(kcAction){
|
|
504
|
+
await this.action(this.uri.auth, {
|
|
505
|
+
kc_action: kcAction
|
|
506
|
+
});
|
|
507
|
+
}
|
|
490
508
|
async _tokenExchange(code, state) {
|
|
491
|
-
window.history.replaceState('', "", this.
|
|
509
|
+
window.history.replaceState('', "", this.uri.redirect);
|
|
492
510
|
const stateAndVerifier = this.storage.pop(AuthorizationCodeFlow.PKCE_AND_STATE_KEY);
|
|
493
511
|
if (stateAndVerifier.state !== state) {
|
|
494
512
|
throw new Error("State mismatch");
|
|
495
513
|
}
|
|
496
|
-
const response = await fetch(this.
|
|
514
|
+
const response = await fetch(this.uri.token, {
|
|
497
515
|
method: "POST",
|
|
498
516
|
headers: {
|
|
499
517
|
"Content-Type": 'application/x-www-form-urlencoded'
|
|
@@ -504,7 +522,7 @@ class AuthorizationCodeFlow {
|
|
|
504
522
|
["grant_type", "authorization_code"],
|
|
505
523
|
["code_verifier", stateAndVerifier.verifier],
|
|
506
524
|
["state", stateAndVerifier.state],
|
|
507
|
-
["redirect_uri", this.
|
|
525
|
+
["redirect_uri", this.uri.redirect]
|
|
508
526
|
])
|
|
509
527
|
});
|
|
510
528
|
if (!response.ok) {
|
|
@@ -512,7 +530,7 @@ class AuthorizationCodeFlow {
|
|
|
512
530
|
throw new Error("Error:" + response.status + ": " + text);
|
|
513
531
|
}
|
|
514
532
|
const token = await response.json();
|
|
515
|
-
return new AuthorizationCodeFlowSession(this.clientId, token, this.
|
|
533
|
+
return new AuthorizationCodeFlowSession(this.clientId, token, this.uri);
|
|
516
534
|
}
|
|
517
535
|
async ensureLoggedIn() {
|
|
518
536
|
const url = new URL(window.location.href);
|
|
@@ -523,7 +541,7 @@ class AuthorizationCodeFlow {
|
|
|
523
541
|
return await this._tokenExchange(code, state);
|
|
524
542
|
}
|
|
525
543
|
//if not authorized
|
|
526
|
-
await this.
|
|
544
|
+
await this.action(this.uri.auth, {});
|
|
527
545
|
return null;
|
|
528
546
|
}
|
|
529
547
|
}
|
|
@@ -532,27 +550,26 @@ AuthorizationCodeFlow.PKCE_AND_STATE_KEY = "state-and-verifier";
|
|
|
532
550
|
class AuthorizationCodeFlowSession {
|
|
533
551
|
static parseToken(token) {
|
|
534
552
|
const [rawHeader, rawPayload, signature] = token.split(".");
|
|
553
|
+
const ut8decoder = new TextDecoder("utf-8");
|
|
535
554
|
return {
|
|
536
|
-
header: JSON.parse(
|
|
537
|
-
payload: JSON.parse(
|
|
555
|
+
header: JSON.parse(ut8decoder.decode(Base64.decode(rawHeader, Base64.STANDARD))),
|
|
556
|
+
payload: JSON.parse(ut8decoder.decode(Base64.decode(rawPayload, Base64.STANDARD))),
|
|
538
557
|
signature: signature
|
|
539
558
|
};
|
|
540
559
|
}
|
|
541
|
-
constructor(clientId,
|
|
560
|
+
constructor(clientId, t, {token, logout, redirect}) {
|
|
542
561
|
this.clientId = clientId;
|
|
543
|
-
this.token =
|
|
544
|
-
this.
|
|
545
|
-
this.
|
|
546
|
-
this.
|
|
547
|
-
this.accessToken = AuthorizationCodeFlowSession.parseToken(token.access_token);
|
|
548
|
-
this.refreshToken = AuthorizationCodeFlowSession.parseToken(token.refresh_token);
|
|
562
|
+
this.token = t;
|
|
563
|
+
this.accessToken = AuthorizationCodeFlowSession.parseToken(t.access_token);
|
|
564
|
+
this.refreshToken = AuthorizationCodeFlowSession.parseToken(t.refresh_token);
|
|
565
|
+
this.uri = { token, logout, redirect };
|
|
549
566
|
this.refreshCallback = null;
|
|
550
567
|
}
|
|
551
568
|
onRefresh(callback) {
|
|
552
569
|
this.refreshCallback = callback;
|
|
553
570
|
}
|
|
554
571
|
async refresh() {
|
|
555
|
-
const response = await fetch(this.
|
|
572
|
+
const response = await fetch(this.uri.token, {
|
|
556
573
|
method: "POST",
|
|
557
574
|
headers: {
|
|
558
575
|
"Content-Type": 'application/x-www-form-urlencoded'
|
|
@@ -588,8 +605,8 @@ class AuthorizationCodeFlowSession {
|
|
|
588
605
|
await this.refresh();
|
|
589
606
|
}
|
|
590
607
|
logout() {
|
|
591
|
-
const url = new URL(this.
|
|
592
|
-
url.searchParams.set("post_logout_redirect_uri", this.
|
|
608
|
+
const url = new URL(this.uri.logout);
|
|
609
|
+
url.searchParams.set("post_logout_redirect_uri", this.uri.redirect);
|
|
593
610
|
url.searchParams.set("id_token_hint", this.token.id_token);
|
|
594
611
|
window.location = url;
|
|
595
612
|
}
|
|
@@ -609,13 +626,12 @@ class AuthorizationCodeFlowInterceptor {
|
|
|
609
626
|
this.gracePeriodBefore = gracePeriodBefore || 2000;
|
|
610
627
|
this.gracePeriodAfter = gracePeriodAfter || 30000;
|
|
611
628
|
}
|
|
612
|
-
async
|
|
629
|
+
async intercept(request, chain) {
|
|
613
630
|
await this.session.refreshIf(this.gracePeriodBefore);
|
|
614
631
|
const headers = new Headers(request.options.headers);
|
|
615
632
|
headers.set("Authorization", this.session.bearerToken());
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
async after(request, response) {
|
|
633
|
+
request.options.headers = headers;
|
|
634
|
+
const response = await chain.proceed(request);
|
|
619
635
|
await this.session.refreshIf(this.gracePeriodAfter);
|
|
620
636
|
return response;
|
|
621
637
|
}
|