pubnub
Version:
Publish & Subscribe Real-time Messaging with PubNub
286 lines (231 loc) • 7.52 kB
JavaScript
/* @flow */
import Config from './config';
import {
TokensDefinition,
GetTokensInput,
GrantTokenOutput,
} from '../flow_interfaces';
export default class {
_config: Config;
_cbor: any;
_userTokens: { [string]: string};
_spaceTokens: { [string]: string};
_userToken: ?string;
_spaceToken: ?string;
constructor(config: Config, cbor: any) {
this._config = config;
this._cbor = cbor;
this._initializeTokens();
}
_initializeTokens() {
this._userTokens = {};
this._spaceTokens = {};
this._userToken = undefined;
this._spaceToken = undefined;
}
_setToken(token: string) {
let tokenObject: GrantTokenOutput = this.parseToken(token);
if (tokenObject && tokenObject.resources) {
if (tokenObject.resources.users) {
Object.keys(tokenObject.resources.users).forEach((id) => {
this._userTokens[id] = token;
});
}
if (tokenObject.resources.spaces) {
Object.keys(tokenObject.resources.spaces).forEach((id) => {
this._spaceTokens[id] = token;
});
}
}
if (tokenObject && tokenObject.patterns) {
if (tokenObject.patterns.users && Object.keys(tokenObject.patterns.users).length > 0) {
this._userToken = token;
}
if (tokenObject.patterns.spaces && Object.keys(tokenObject.patterns.spaces).length > 0) {
this._spaceToken = token;
}
}
}
setToken(token: string) {
if (token && token.length > 0) {
this._setToken(token);
}
}
setTokens(tokens: string[]) {
if (tokens && tokens.length && typeof tokens === 'object') {
tokens.forEach((token) => {
this.setToken(token);
});
}
}
getTokens(tokenDef: GetTokensInput): TokensDefinition {
let result: TokensDefinition = {
users: {},
spaces: {}
};
if (tokenDef) {
if (tokenDef.user) {
result.user = this._userToken;
}
if (tokenDef.space) {
result.space = this._spaceToken;
}
if (tokenDef.users) {
tokenDef.users.forEach((user) => {
result.users[user] = this._userTokens[user];
});
}
if (tokenDef.space) {
tokenDef.spaces.forEach((space) => {
result.spaces[space] = this._spaceTokens[space];
});
}
} else {
if (this._userToken) {
result.user = this._userToken;
}
if (this._spaceToken) {
result.space = this._spaceToken;
}
Object.keys(this._userTokens).forEach((user) => {
result.users[user] = this._userTokens[user];
});
Object.keys(this._spaceTokens).forEach((space) => {
result.spaces[space] = this._spaceTokens[space];
});
}
return result;
}
getToken(type: string, id?: string) {
let result;
if (id) {
if (type === 'user') {
result = this._userTokens[id];
} else if (type === 'space') {
result = this._spaceTokens[id];
}
} else if (type === 'user') {
result = this._userToken;
} else if (type === 'space') {
result = this._spaceToken;
}
return result;
}
extractPermissions(permissions: number) {
let permissionsResult = {
create: false,
read: false,
write: false,
manage: false,
delete: false,
};
/* eslint-disable */
if ((permissions & 16) === 16) {
permissionsResult.create = true;
}
if ((permissions & 8) === 8) {
permissionsResult.delete = true;
}
if ((permissions & 4) === 4) {
permissionsResult.manage = true;
}
if ((permissions & 2) === 2) {
permissionsResult.write = true;
}
if ((permissions & 1) === 1) {
permissionsResult.read = true;
}
/* eslint-enable */
return permissionsResult;
}
parseToken(tokenString: string): GrantTokenOutput {
let parsed = this._cbor.decodeToken(tokenString);
if (parsed !== undefined) {
let userResourcePermissions = Object.keys(parsed.res.usr);
let spaceResourcePermissions = Object.keys(parsed.res.spc);
let channelResourcePermissions = Object.keys(parsed.res.chan);
let groupResourcePermissions = Object.keys(parsed.res.grp);
let userPatternPermissions = Object.keys(parsed.pat.usr);
let spacePatternPermissions = Object.keys(parsed.pat.spc);
let channelPatternPermissions = Object.keys(parsed.pat.chan);
let groupPatternPermissions = Object.keys(parsed.pat.grp);
let result: GrantTokenOutput = {
version: parsed.v,
timestamp: parsed.t,
ttl: parsed.ttl
};
let userResources = userResourcePermissions.length > 0;
let spaceResources = spaceResourcePermissions.length > 0;
let channelResources = channelResourcePermissions.length > 0;
let groupResources = groupResourcePermissions.length > 0;
if (userResources || spaceResources || channelResources || groupResources) {
result.resources = {};
if (userResources) {
result.resources.users = {};
userResourcePermissions.forEach((id) => {
result.resources.users[id] = this.extractPermissions(parsed.res.usr[id]);
});
}
if (spaceResources) {
result.resources.spaces = {};
spaceResourcePermissions.forEach((id) => {
result.resources.spaces[id] = this.extractPermissions(parsed.res.spc[id]);
});
}
if (channelResources) {
result.resources.channels = {};
channelResourcePermissions.forEach((id) => {
result.resources.channels[id] = this.extractPermissions(parsed.res.chan[id]);
});
}
if (groupResources) {
result.resources.groups = {};
groupResourcePermissions.forEach((id) => {
result.resources.groups[id] = this.extractPermissions(parsed.res.grp[id]);
});
}
}
let userPatterns = userPatternPermissions.length > 0;
let spacePatterns = spacePatternPermissions.length > 0;
let channelPatterns = channelPatternPermissions.length > 0;
let groupPatterns = groupPatternPermissions.length > 0;
if (userPatterns || spacePatterns || channelPatterns || groupPatterns) {
result.patterns = {};
if (userPatterns) {
result.patterns.users = {};
userPatternPermissions.forEach((id) => {
result.patterns.users[id] = this.extractPermissions(parsed.pat.usr[id]);
});
}
if (spacePatterns) {
result.patterns.spaces = {};
spacePatternPermissions.forEach((id) => {
result.patterns.spaces[id] = this.extractPermissions(parsed.pat.spc[id]);
});
}
if (channelPatterns) {
result.patterns.channels = {};
channelPatternPermissions.forEach((id) => {
result.patterns.channels[id] = this.extractPermissions(parsed.pat.chan[id]);
});
}
if (groupPatterns) {
result.patterns.groups = {};
groupPatternPermissions.forEach((id) => {
result.patterns.groups[id] = this.extractPermissions(parsed.pat.grp[id]);
});
}
}
if (Object.keys(parsed.meta).length > 0) {
result.meta = parsed.meta;
}
result.signature = parsed.sig;
return result;
} else {
return undefined;
}
}
clearTokens() {
this._initializeTokens();
}
}