UNPKG

integreat

Version:
116 lines 5.07 kB
import { isObject } from '../utils/is.js'; import { createErrorResponse } from '../utils/response.js'; const MAX_RETRIES = 1; const shouldRetry = (authentication, retryCount) => authentication?.status === 'timeout' && retryCount < MAX_RETRIES; const getAuthKey = (authenticator, options, action) => typeof authenticator.extractAuthKey === 'function' ? authenticator.extractAuthKey(options, action) || '' : ''; export default class Auth { id; #authenticator; #options; #overrideAuthAsMethod; #authentications = new Map(); constructor(id, authenticator, options, overrideAuthAsMethod) { this.id = id; this.#authenticator = authenticator; this.#options = options || {}; this.#overrideAuthAsMethod = overrideAuthAsMethod; } async authenticate(action, dispatch) { const authKey = getAuthKey(this.#authenticator, this.#options, action); let authentication = this.#authentications.get(authKey); if (authentication?.status === 'granted' && this.#authenticator.isAuthenticated(authentication, this.#options, action)) { return true; } let attempt = 0; do { authentication = await this.#authenticator.authenticate(this.#options, action, dispatch, authentication || null); } while (shouldRetry(authentication, attempt++)); this.#authentications.set(authKey, authentication); return authentication?.status === 'granted'; } async validate(authentication, action, dispatch) { if (typeof this.#authenticator.validate !== 'function') { return createErrorResponse(`Could not authenticate. Authenticator '${this.#authenticator.id}' doesn't support validation`, this.id, 'autherror'); } if (authentication.status !== 'granted') { return createErrorResponse('Authentication was refused', this.id, 'noaccess'); } const response = await this.#authenticator.validate(authentication, this.#options, action, dispatch); if (response.status === 'ok' && response.access?.ident) { return response; } else { return createErrorResponse(`Authentication was refused. ${response.error}`, this.id, response.status || 'autherror', response.reason); } } async authenticateAndGetAuthObject(action, authAsMethod, dispatch) { const fn = this.#authenticator.authentication[authAsMethod]; if (typeof fn === 'function') { const auth = await this.#authenticator.authenticate(this.#options, action, dispatch, null); if (auth.status === 'granted') { return fn(auth); } else { throw new Error(auth.error || 'Authentication failed'); } } return null; } getAuthObject(transporter, action, providedAuthKey) { const authKey = providedAuthKey ?? getAuthKey(this.#authenticator, this.#options, action); const auth = this.#authentications.get(authKey); if (!auth || auth.status !== 'granted') { return null; } const authenticator = this.#authenticator; const authAsMethod = this.#overrideAuthAsMethod || transporter.defaultAuthAsMethod || transporter.authentication; const authObjectFn = isObject(authenticator?.authentication) && typeof authAsMethod === 'string' && authenticator.authentication[authAsMethod]; return typeof authObjectFn === 'function' ? authObjectFn(auth) : null; } getResponseFromAuth(authKey = '') { const auth = this.#authentications.get(authKey); if (!auth) { return { status: 'noaccess', error: `Trying to use auth '${this.id}' before authentication has been run`, }; } if (auth.status === 'granted') { return { status: 'ok' }; } const status = auth.status === 'refused' ? 'noaccess' : 'autherror'; const error = auth.status === 'refused' ? `Authentication attempt for auth '${this.id}' was refused.` : `Could not authenticate auth '${this.id}'. [${auth.status}]`; return { status, error: [error, auth.error].filter(Boolean).join(' ') }; } applyToAction(action, transporter) { const authKey = getAuthKey(this.#authenticator, this.#options, action); const auth = this.#authentications.get(authKey); if (auth?.status === 'granted') { return { ...action, meta: { ...action.meta, auth: this.getAuthObject(transporter, action, authKey), }, }; } return { ...action, response: { ...action.response, ...this.getResponseFromAuth(authKey), }, meta: { ...action.meta, auth: null }, }; } } //# sourceMappingURL=Auth.js.map