@optionfactory/ful 0.17.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 +2 -2
- package/dist/ful.iife.js +75 -60
- 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 +75 -60
- 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\n async ensureLoggedIn() {\n const url = new URL(window.location.href);\n const code = url.searchParams.get(\"code\");\n if (code) {\n //if callback from keycloak\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,19 +530,18 @@ 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
|
-
|
|
518
535
|
async ensureLoggedIn() {
|
|
519
536
|
const url = new URL(window.location.href);
|
|
520
537
|
const code = url.searchParams.get("code");
|
|
521
|
-
if (code) {
|
|
522
|
-
//if callback from keycloak
|
|
538
|
+
if (code && this.storage.load(AuthorizationCodeFlow.PKCE_AND_STATE_KEY)) {
|
|
539
|
+
//if callback from keycloak and we have our state still stored
|
|
523
540
|
const state = url.searchParams.get("state");
|
|
524
541
|
return await this._tokenExchange(code, state);
|
|
525
542
|
}
|
|
526
543
|
//if not authorized
|
|
527
|
-
await this.
|
|
544
|
+
await this.action(this.uri.auth, {});
|
|
528
545
|
return null;
|
|
529
546
|
}
|
|
530
547
|
}
|
|
@@ -533,27 +550,26 @@ AuthorizationCodeFlow.PKCE_AND_STATE_KEY = "state-and-verifier";
|
|
|
533
550
|
class AuthorizationCodeFlowSession {
|
|
534
551
|
static parseToken(token) {
|
|
535
552
|
const [rawHeader, rawPayload, signature] = token.split(".");
|
|
553
|
+
const ut8decoder = new TextDecoder("utf-8");
|
|
536
554
|
return {
|
|
537
|
-
header: JSON.parse(
|
|
538
|
-
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))),
|
|
539
557
|
signature: signature
|
|
540
558
|
};
|
|
541
559
|
}
|
|
542
|
-
constructor(clientId,
|
|
560
|
+
constructor(clientId, t, {token, logout, redirect}) {
|
|
543
561
|
this.clientId = clientId;
|
|
544
|
-
this.token =
|
|
545
|
-
this.
|
|
546
|
-
this.
|
|
547
|
-
this.
|
|
548
|
-
this.accessToken = AuthorizationCodeFlowSession.parseToken(token.access_token);
|
|
549
|
-
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 };
|
|
550
566
|
this.refreshCallback = null;
|
|
551
567
|
}
|
|
552
568
|
onRefresh(callback) {
|
|
553
569
|
this.refreshCallback = callback;
|
|
554
570
|
}
|
|
555
571
|
async refresh() {
|
|
556
|
-
const response = await fetch(this.
|
|
572
|
+
const response = await fetch(this.uri.token, {
|
|
557
573
|
method: "POST",
|
|
558
574
|
headers: {
|
|
559
575
|
"Content-Type": 'application/x-www-form-urlencoded'
|
|
@@ -589,8 +605,8 @@ class AuthorizationCodeFlowSession {
|
|
|
589
605
|
await this.refresh();
|
|
590
606
|
}
|
|
591
607
|
logout() {
|
|
592
|
-
const url = new URL(this.
|
|
593
|
-
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);
|
|
594
610
|
url.searchParams.set("id_token_hint", this.token.id_token);
|
|
595
611
|
window.location = url;
|
|
596
612
|
}
|
|
@@ -610,13 +626,12 @@ class AuthorizationCodeFlowInterceptor {
|
|
|
610
626
|
this.gracePeriodBefore = gracePeriodBefore || 2000;
|
|
611
627
|
this.gracePeriodAfter = gracePeriodAfter || 30000;
|
|
612
628
|
}
|
|
613
|
-
async
|
|
629
|
+
async intercept(request, chain) {
|
|
614
630
|
await this.session.refreshIf(this.gracePeriodBefore);
|
|
615
631
|
const headers = new Headers(request.options.headers);
|
|
616
632
|
headers.set("Authorization", this.session.bearerToken());
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
async after(request, response) {
|
|
633
|
+
request.options.headers = headers;
|
|
634
|
+
const response = await chain.proceed(request);
|
|
620
635
|
await this.session.refreshIf(this.gracePeriodAfter);
|
|
621
636
|
return response;
|
|
622
637
|
}
|