Skip to content

Instantly share code, notes, and snippets.

@gaspard
Created October 24, 2018 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaspard/7b6e49e3201661292aa450edf55e37f7 to your computer and use it in GitHub Desktop.
Save gaspard/7b6e49e3201661292aa450edf55e37f7 to your computer and use it in GitHub Desktop.
async function updateAccessChangeLog(
type: 'user' | 'collection',
currentUser: UserWithKeys,
now: number,
// Old item
oldItem: Item,
// New userAccess
newItem: Item
) {
// collectionAccess: Item belongs to collections
// userAccess: Item can be edited by users
const newAccess =
type === 'user' ? newItem.userAccess : newItem.collectionAccess
const oldAccess =
type === 'user' ? oldItem.userAccess : oldItem.collectionAccess
const oldIds = Object.keys(oldAccess)
const newIds = Object.keys(newAccess)
const add = newIds.filter(k => !oldAccess[k])
const remove = oldIds.filter(k => !newAccess[k])
const update = newIds.filter(
k =>
oldAccess[k] &&
JSON.stringify(newAccess[k]) !== JSON.stringify(oldAccess[k])
)
const ops = { add, update, remove }
// Create accessLog entries
let previous = oldItem.id
let accessChangeLog: AccessChangeLogEntry[] = []
if (newItem.accessChangeLog) {
accessChangeLog = newItem.accessChangeLog.slice()
const last = accessChangeLog.slice(-1)[0]
if (last) {
const { signature64 } = extractJWT(last.operation)
previous = signature64
}
}
newItem.accessChangeLog = accessChangeLog
const opsKeys = Object.keys(ops) as (keyof typeof ops)[]
for (let i = 0; i < opsKeys.length; i++) {
const opType = opsKeys[i]
const ids = ops[opType]
for (let j = 0; j < ids.length; j++) {
const id = ids[j]
const value = newAccess[id]
const op: AccessChangeOperation = {
// Changed timestamp.
changedAt: now,
// Signature of previous operation. Contains itemId for first operation.
previous,
// Type of access operation.
type,
// Concerned field in userAccess or collectionAccess.
id,
// Operation name.
operation: opType,
}
if (type === 'user' && opType !== 'remove') {
const val = value as CollectionUserAccess['id']
// Changed access.
op.access = val.access
if (opType === 'add' && val.invite) {
op.operation = 'invite'
} else if (currentUser.user.id === id) {
op.operation = 'join'
}
}
const signedOperation = await sign(currentUser.signKey, op)
previous = extractJWT(signedOperation).signature64
accessChangeLog.push({
changedBy: currentUser.user.id,
operation: signedOperation,
})
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment