@aimee-blue/ab-service-kit
Version:
Aimee Blue Service Template
107 lines (84 loc) • 3.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.epicWithAuth = epicWithAuth;
var _operators = require("rxjs/operators");
var _rxjs = require("rxjs");
var _abContracts = require("@aimee-blue/ab-contracts");
var _abAuth = require("@aimee-blue/ab-auth");
var _ofType = require("../ofType");
var _verifyToken = require("./verifyToken");
var _publishStream = require("../publishStream");
var _abShared = require("@aimee-blue/ab-shared");
var _verifyError = require("./verifyError");
var _registerError = require("../registerError");
const defaultDeps = {
verifyToken: (...args) => (0, _rxjs.from)((0, _verifyToken.verifyToken)(...args)),
decodeJwt: _abAuth.decodeJwt
};
function firstMessageShouldBeAuth() {
return commands => commands.pipe((0, _operators.take)(1), (0, _operators.map)(msg => {
if (msg.type !== _abContracts.Auth.AUTH) {
throw new Error('No token received');
}
return msg;
}), (0, _ofType.ofType)(_abContracts.Auth.AUTH));
}
const VERIFY_TOKEN_REQUEST_SUCCESS_PREFIX = 'verifyAuth succeeded with non-ok status';
function verifyTokensUsingAuthMessage(allow, deps) {
return commands => commands.pipe((0, _operators.concatMap)(auth => deps.verifyToken({
token: auth.payload.token,
allow
}).pipe((0, _operators.switchMap)(result => {
const decoded = deps.decodeJwt(auth.payload.token);
if (typeof result === 'object' && result !== null && result.status === 200) {
return (0, _rxjs.of)(decoded.payload);
} else {
throw new _verifyError.VerifyError(`${VERIFY_TOKEN_REQUEST_SUCCESS_PREFIX} ${result.status} - ${result.message}`, decoded);
}
}))));
}
function epicWithAuth(allow, epic, deps = defaultDeps) {
const authForEpic = _abShared.Utils.setFunctionName(`withAuth.${epic.name}`, (...[cmd, ctx, ...rest]) => {
return new _rxjs.Observable(subscriber => {
const commands = (0, _publishStream.publishStream)(cmd);
const authOp = (0, _publishStream.publishStream)(commands.pipe(firstMessageShouldBeAuth(), verifyTokensUsingAuthMessage(allow, deps)));
const authSuccessOrEmpty = authOp.pipe((0, _operators.catchError)(() => (0, _rxjs.empty)()));
const authFailed = authOp.pipe((0, _operators.ignoreElements)(), (0, _operators.catchError)(err => {
const error = _abShared.Errors.ensureError(err);
if (error instanceof _verifyError.VerifyError) {
var _error$token;
const payload = (_error$token = error.token) === null || _error$token === void 0 ? void 0 : _error$token.payload;
if (payload && payload.isConsole && !payload.isHil) {
(0, _registerError.registerError)(error);
ctx.logger.error('💥 Console user authentication failed: ', error);
} else {
// probably just a sleeping HIL tab:
ctx.logger.log(error.message);
}
} else {
ctx.logger.error('💥 Verify token request failed: ', error);
}
const appError = {
type: _abContracts.Apps.ERROR,
payload: {
status: 'UNAUTHENTICATED',
message: 'Unauthenticated'
}
};
return (0, _rxjs.of)(appError);
}));
const result = (0, _rxjs.merge)(authFailed, authSuccessOrEmpty.pipe( // buffer commands while authOp is in progress:
(0, _operators.withLatestFrom)(commands.pipe((0, _operators.skip)(1), (0, _operators.buffer)(authSuccessOrEmpty.pipe((0, _operators.take)(1))), (0, _operators.take)(1))), (0, _operators.switchMap)(([auth, buffered]) => {
ctx.auth = auth;
return epic((0, _rxjs.concat)((0, _rxjs.from)(buffered), commands), ctx, ...rest);
})));
subscriber.add(result.subscribe(subscriber));
subscriber.add(authOp.connect());
subscriber.add(commands.connect());
});
});
return authForEpic;
}
//# sourceMappingURL=epicWithAuth.js.map