@velas/account-agent
Version:
sdk
188 lines (142 loc) • 5.8 kB
JavaScript
import ttl from './ttl';
const NON_REJECTABLE_SCOPES = new Set(['openid']);
function getSession(store, keyStore) {
function getterSetTransformation(value) {
if (Array.isArray(value)) {
return new Set(value);
}
if (typeof value === 'undefined') {
return new Set();
}
throw new Error('expected Array to be stored');
}
function setterSetValidation(values, forbiddenMembers = [], ignoredMembers = []) {
if (Array.isArray(values)) {
values = new Set(values);
} else if (!(values instanceof Set)) {
throw new Error('expected Array or Set');
}
forbiddenMembers.forEach((forbidden) => {
if (values.has(forbidden)) {
throw new Error(`${forbidden} cannot be rejected`);
}
});
ignoredMembers.forEach(Set.prototype.delete.bind(values));
return [...values];
}
function Session(options) {
this.account = options.account;
this.op_key = options.op_key;
this.authorizations = options.authorizations || {};
this.type = options.type
this.storage = store;
this.keyStorage = keyStore;
}
Session.prototype.save = async function () {
const { account, op_key, authorizations, type } = this;
const payload = {
account,
op_key,
authorizations,
type
};
this.storage.setItem(`${'Session'}:${op_key}`, payload, {
issuer: 'agent',
expires: new Date().getTime() + ttl.session,
});
await this.keyStorage.updateKeyWithAccount(op_key, account);
};
Session.findById = async function (op_key, storage = store) {
const foundSession = await storage.getItem(`${'Session'}:${op_key}`);
if (!foundSession) return undefined;
return new this(foundSession);
};
Session.prototype.destroy = async function() {
const { op_key, authorizations } = this;
await this.keyStorage.destroy(op_key);
const client_ids = Object.keys(authorizations || {});
for (const client_id of client_ids) {
const { grant_id } = authorizations[client_id];
if (grant_id) {
await this.storage.removeItem(`${'Token'}:${grant_id}`);
};
};
this.storage.removeItem(`${'Session'}:${op_key}`);
};
Session.prototype.logout = async function(client_to_destroy) {
const { grant_id } = this.authorizationFor(client_to_destroy);
if (grant_id) await this.storage.removeItem(`${'Token'}:${grant_id}`);
delete this.authorizations[client_to_destroy];
await this.save();
};
Session.find = async function (storage = store) {
const foundSessions = await storage.getItems('Session');
return foundSessions.map((item) => {
try { return new this(item) } catch(_) {};
return undefined;
}).filter(Boolean);
};
Session.prototype.authorizationFor = function (client_id) {
this.authorizations = this.authorizations || {};
if (!this.authorizations[client_id]) {
this.authorizations[client_id] = {};
}
return this.authorizations[client_id];
}
Session.prototype.grantIdFor = function (client_id, value) {
const authorization = this.authorizationFor(client_id);
if (value) {
authorization.grant_id = value;
return undefined;
}
return authorization.grant_id;
}
Session.prototype.acceptedScopesFor = function (client_id) {
const accepted = new Set(this.promptedScopesFor(client_id));
this.rejectedScopesFor(client_id).forEach(Set.prototype.delete.bind(accepted));
return accepted;
}
Session.prototype.promptedScopesFor = function (client_id, scopes) {
const authorization = this.authorizationFor(client_id);
if (scopes) {
if (authorization.promptedScopes) {
authorization.promptedScopes = [
...new Set([
...authorization.promptedScopes,
...setterSetValidation(scopes),
]),
];
return undefined;
}
authorization.promptedScopes = setterSetValidation(scopes);
return undefined;
}
return getterSetTransformation(authorization.promptedScopes);
}
Session.prototype.clientInfoFor = function (client_id, value) {
const authorization = this.authorizationFor(client_id);
if (value) {
authorization.client_info = value
}
return authorization.client_info
}
Session.prototype.rejectedScopesFor = function (client_id, scopes, replace = false) {
const authorization = this.authorizationFor(client_id);
if (scopes) {
if (replace || !authorization.rejectedScopes) {
authorization.rejectedScopes = setterSetValidation(scopes, NON_REJECTABLE_SCOPES);
return undefined;
}
authorization.rejectedScopes = [
...new Set([
...authorization.rejectedScopes,
...setterSetValidation(scopes, NON_REJECTABLE_SCOPES),
]),
];
return undefined;
}
return getterSetTransformation(authorization.rejectedScopes);
}
return Session;
};
export default getSession;