Last active
May 30, 2022 23:19
-
-
Save rajagp/42327d8ac06fcd6d2d47dffef162631c to your computer and use it in GitHub Desktop.
This file contains 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 sync(doc, oldDoc) { | |
// Every document write is processed by access control function | |
/* Data Validation */ | |
// Validate the presence of email field. | |
validateNotEmpty("email", doc.email); | |
// Validate that the document Id _id is prefixed by owner | |
var expectedDocId = "user" + "::" + doc.email; | |
if (expectedDocId != doc._id) { | |
// reject documents that fail data validation | |
throw({forbidden: "user doc Id must be of form user::email"}); | |
} | |
try { | |
// Check if this is document imported from server. | |
// All server side imports are processed using admin credentials | |
requireAdmin(); | |
if (!isDelete()) { | |
// Derive channel name from content of document. Every user has own channel | |
var username = getEmail(); | |
var channelId = "channel."+ username; | |
// Assign document to channel | |
channel(channelId); | |
// Give user access to channel | |
access(username,channelId); | |
} | |
}catch (error) { | |
// This is not a document import. It is a write coming in from client. | |
console.log("This is not a doc import " + error); | |
// If non admin client replication | |
if (!isDelete()) { | |
/* Authorization */ | |
// Verify the user making the request is the same as the one in doc's email | |
requireUser(doc.email); | |
// Check if document is being created / added for first time | |
// We allow any user to create the document | |
if (isCreate()) { | |
/* Routing */ | |
// Derive channel name using content of document. Every user has own channel. | |
var username = getEmail(); | |
var channelId = "channel."+ username; | |
// Add doc to the channel. | |
channel(channelId); | |
// Give user access to document | |
access(username, channelId); | |
} else { | |
// This is an update | |
// Validate that the email hasn't changed. | |
validateReadOnly("email", doc.email, oldDoc.email); | |
var username = getEmail(); | |
var channelId = "channel."+ username; | |
// Add doc to the user's channel. | |
channel(channelId); | |
// Give user access to channel | |
access(username,channelId); | |
} | |
} | |
} | |
// Helper functions | |
// get type property | |
function getType() { | |
return (isDelete() ? oldDoc.type : doc.type); | |
} | |
// get email Id property | |
function getEmail() { | |
return (isDelete() ? oldDoc.email : doc.email); | |
} | |
// Check if document is being created/added for first time | |
function isCreate() { | |
// Checking false for the Admin UI to work | |
return ((oldDoc == false) || (oldDoc == null || oldDoc._deleted) && !isDelete()); | |
} | |
// Check if this is a document update | |
function isUpdate() { | |
return (!isCreate() && !isDelete()); | |
} | |
// Check if this is a document delete | |
function isDelete() { | |
return (doc._deleted == true); | |
} | |
// Verify that specified property exists | |
function validateNotEmpty(key, value) { | |
if (!value) { | |
throw({forbidden: key + " is not provided."}); | |
} | |
} | |
// Verify that specified property value has not changed during update | |
function validateReadOnly(name, value, oldValue) { | |
if (value != oldValue) { | |
throw({forbidden: name + " is read-only."}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment