@velas/account-agent
Version:
sdk
155 lines (130 loc) • 4.97 kB
JavaScript
/*
* Interaction policy
*/
async function checkPolicy(next) {
const policy = [
{
name: 'login',
checks: [
[
'no_active_sessions', (ctx) => {
if (!ctx.interaction.sessions.length) {
return true;
}
return false;
},
],
],
},
{
name: 'select_account',
checks: [
[
'no_selected_session', (ctx) => {
if (!ctx.interaction.session || !ctx.interaction.session.op_key || !ctx.interaction.session.account) {
return true;
}
return false;
},
],
],
},
{
name: 'merge',
checks: [
[
'active_session_exists', (ctx) => {
const { session: {account, op_key}, sessions} = ctx.interaction;
const selected = sessions.reduce((result,i)=> {
if (i.account === account && i.op_key !== op_key) {
result = i
}
return result
}, undefined);
if (selected) {
if (selected.count === 0) {
ctx.interaction.merge = {
operationalAddress: selected.op_key,
operationalAddressMergeWith: op_key,
}
} else {
ctx.interaction.merge = {
operationalAddress: op_key,
operationalAddressMergeWith: selected.op_key,
}
};
return true;
}
return false;
},
],
],
},
{
name: 'empowerment',
checks: [
[
'no_key_scopes', (ctx) => {
const operationalKeyScopes = ctx.interaction.session.op_key_scopes;
const requestedScopes = ctx.interaction.params.scope;
const empowerment = [];
for (let requestedScope of requestedScopes) {
const scope = requestedScope.split(":")[0] !== ctx.provider.sc.VELAS_ACCOUNT_PROGRAM_ADDRESS ? requestedScope.split(":")[0] : requestedScope;
if (
!operationalKeyScopes.includes(scope) &&
!ctx.provider.sc.PERMITTED_SCOPES.includes(scope)
) {
empowerment.push(scope);
};
};
if(empowerment.length) {
ctx.interaction.empowerment = empowerment;
return true;
};
ctx.interaction.empowerment = [];
return false;
},
],
],
},
{
name: 'consent',
checks: [
[
'scopes_missing', (ctx) => {
const promptedScopes = ctx.interaction.session.promptedScopesFor(ctx.interaction.client.client_id);
const requestedScopes = ctx.interaction.params.scope;
for (const scope of requestedScopes) {
if (!promptedScopes.has(scope)) {
return true;
}
};
return false;
},
],
],
},
];
let results = [];
for (const { name, checks } of policy) {
results = (await Promise.all([...checks].map(async ([ stage_reason, check ]) => {
if ( await check(this) ) {
return {
stage: name,
stage_reason,
};
}
return undefined;
}))).filter(Boolean);
if (results.length) break;
};
if (!results.length) {
this.interaction.stage = 'completed';
this.interaction.stage_reason = 'all_policies_are_checked';
} else {
this.interaction.stage = results[0].stage;
this.interaction.stage_reason = results[0].stage_reason;
}
await next();
};
export default checkPolicy;