-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: conversation roles and permissions
there are a lot of changes in this commit but the roles and permissions are the most major. - added scripts to reset the developer database and keydb. - removed console.log of the database url in migrations. - removed unnecessary relationNames in the db schema. - added common helper which has a throwError function. - added conversation helper for common functions. - ensured that conversation queries/mutations are prefixed with "user". - implemented adding and removing of participants. - added defaults for limit and offset for getting messages. - updated/added types to reflect the new roles and permissions.
- Loading branch information
Showing
18 changed files
with
577 additions
and
236 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/bash | ||
|
||
rm -f drizzle/\*.sql | ||
rm -rf drizzle/meta | ||
docker exec -ti nova-postgres dropdb -U postgres -f 'nova' | ||
docker exec -ti nova-postgres createdb -U postgres 'nova' |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
|
||
docker exec -ti nova-keydb redis-cli flushall |
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { GraphQLError } from 'graphql'; | ||
|
||
const throwError = (message: string, code: string) => { | ||
throw new GraphQLError(message, { extensions: { code } }); | ||
}; | ||
|
||
export { throwError }; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { db } from '../../drizzle/db'; | ||
import { throwError } from '../common'; | ||
|
||
const getConversation = async (id: string) => { | ||
const conversation = await db.query.userConversation.findFirst({ | ||
where: (userConversation, { eq }) => eq(userConversation.id, id) | ||
}); | ||
if (!conversation) | ||
throwError( | ||
'The conversation does not exist.', | ||
'CONVERSATION_NOT_FOUND' | ||
); | ||
return conversation; | ||
}; | ||
|
||
const getParticipant = async (userId: string, conversationId: string) => { | ||
await getConversation(conversationId); | ||
const participant = await db.query.userConversationParticipant.findFirst({ | ||
where: (userConversationParticipant, { and, eq }) => | ||
and( | ||
eq(userConversationParticipant.conversationId, conversationId), | ||
eq(userConversationParticipant.userId, userId) | ||
), | ||
with: { | ||
roles: { | ||
with: { | ||
role: { | ||
with: { | ||
members: true | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
if (!participant) | ||
throwError( | ||
'You must be a participant in this conversation to proceed with this action.', | ||
'CONVERSATION_PARTICIPANT_REQUIRED' | ||
); | ||
return participant; | ||
}; | ||
|
||
const getPermissions = async (conversationId: string, userId: string) => { | ||
const participant = await getParticipant(userId, conversationId); | ||
var perms = []; | ||
for (const role of participant?.roles ?? []) { | ||
for (const permission of JSON.parse(role.role.permissions)) { | ||
perms.push(permission); | ||
} | ||
} | ||
return perms; | ||
}; | ||
|
||
const checkPermissions = async ( | ||
permissions: string[], | ||
conversationId: string, | ||
userId: string | ||
) => { | ||
const _permissions = await getPermissions(conversationId, userId); | ||
const missing = permissions.filter((p) => !_permissions.includes(p)); | ||
|
||
if (missing.length > 0) { | ||
throwError( | ||
`You do not have permission to proceed with this action. Missing permission(s): ${missing.join( | ||
', ' | ||
)}`, | ||
'CONVERSATION_PERMISSIONS_MISSING' | ||
); | ||
} | ||
}; | ||
|
||
export { getConversation, getParticipant, getPermissions, checkPermissions }; |
Oops, something went wrong.