Last active
July 19, 2018 02:04
-
-
Save ianjennings/691e177d87a3cfa0a00d165b4792f5ef to your computer and use it in GitHub Desktop.
This is an example auth policy for PubNub ChatEngine that sets the first user to enter a new private chat as the owner. Any additional users must be invited by a user that is already in the chat.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // function to check if a uuid (who) exists in a db record (and is permitted in the channel) | |
| let isAuthed = (record, who) => { | |
| if (!record) { | |
| return true; | |
| } else { | |
| return who && record && record.length > 0 && record.indexOf(who) > -1; | |
| } | |
| }; | |
| // this is a function to permit a uuid within a chatengine channel | |
| let authInChannel = (record, who) => { | |
| // create an empty array if a falsey value is provided | |
| record = record || []; | |
| // this is the kv store key we'll use to look up the record | |
| let key = ['authed', body.chat.channel].join(':'); | |
| // if the uuid is not already in the record | |
| if (record.indexOf(who) === -1) { | |
| // add it to the record | |
| record.push(who); | |
| // save the record in the db | |
| return db.set(key, record, 525600).then(() => { | |
| return allow(); | |
| }).catch((err) => { | |
| console.error(err); | |
| return serverError('Internal Server Error'); | |
| }); | |
| } else { | |
| // otherwise, the uuid is already in the record. do not duplicate | |
| return allow(); | |
| } | |
| }; | |
| // this is the auth policy that runs on every request | |
| let authPolicy = () => { | |
| // run this logic on invite route only | |
| if (route === 'invite') { | |
| // if the chat is not private, don't do anything | |
| if (!body.chat.private) { | |
| return allow(); | |
| } else { | |
| // this is the record we'll look up in the kv store to add the invited user into | |
| key = ['authed', body.chat.channel].join(':'); | |
| // get the record | |
| return db.get(key).then((record) => { | |
| // check that the current user is already authenticatd in this channel (see /grant below) | |
| if (isAuthed(record, body.uuid)) { | |
| // if this user is authentiated, grant the INVITED USER (body.to) | |
| return authInChannel(record, body.to); | |
| } else { | |
| // if the uuid is not in the record, then return unauthorized | |
| return unauthorized(); | |
| } | |
| }).catch((err) => { | |
| // handle errors on record lookup | |
| console.error(err); | |
| return serverError('Internal Server Error'); | |
| }); | |
| } | |
| // this is when the client requests PAM access to a chat | |
| // if this is the first time a chat is made, the first user to make the chat is authed automatically | |
| } else if (route === 'grant') { | |
| // make sure the chat is set as private before executing logic | |
| if (proxyBody.chat.private) { | |
| // look up the reocrd to see if this use is permitted | |
| let key = ['authed', body.chat.channel].join(':'); | |
| return db.get(key).then((record) => { | |
| // isAuthed will return true if the record is empty | |
| // this means the first user to be invited is permitted | |
| if (isAuthed(record, body.uuid)) { | |
| // permit the user | |
| return authInChannel(record, body.uuid); | |
| } else { | |
| return unauthorized(); | |
| } | |
| }).catch((err) => { | |
| // handle errors | |
| console.error(err); | |
| return die('Internal Server Error'); | |
| }); | |
| } else { | |
| return allow(); | |
| } | |
| } else { | |
| // all other requests | |
| return allow(); | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment