mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
complex email notification settings
This commit is contained in:
parent
16ecfab216
commit
14fefd2cfc
@ -70,7 +70,13 @@ Factory.define('basicUser')
|
||||
termsAndConditionsAgreedAt: '2019-08-01T10:47:19.212Z',
|
||||
allowEmbedIframes: false,
|
||||
showShoutsPublicly: false,
|
||||
sendNotificationEmails: true,
|
||||
emailNotificationsCommentOnObservedPost: true,
|
||||
emailNotificationsPostByFollowedUser: true,
|
||||
emailNotificationsPostInGroup: true,
|
||||
emailNotificationsGroupMemberJoined: true,
|
||||
emailNotificationsGroupMemberLeft: true,
|
||||
emailNotificationsGroupMemberRemoved: true,
|
||||
emailNotificationsGroupMemberRoleChanged: true,
|
||||
locale: 'en',
|
||||
})
|
||||
.attr('slug', ['slug', 'name'], (slug, name) => {
|
||||
|
||||
@ -53,19 +53,25 @@ const createDefaultAdminUser = async (session) => {
|
||||
`MERGE (e:EmailAddress {
|
||||
email: "${defaultAdmin.email}",
|
||||
createdAt: toString(datetime())
|
||||
})-[:BELONGS_TO]->(u:User {
|
||||
name: "${defaultAdmin.name}",
|
||||
encryptedPassword: "${defaultAdmin.password}",
|
||||
role: "admin",
|
||||
id: "${defaultAdmin.id}",
|
||||
slug: "${defaultAdmin.slug}",
|
||||
createdAt: toString(datetime()),
|
||||
allowEmbedIframes: false,
|
||||
showShoutsPublicly: false,
|
||||
sendNotificationEmails: true,
|
||||
deleted: false,
|
||||
disabled: false
|
||||
})-[:PRIMARY_EMAIL]->(e)`,
|
||||
})-[:BELONGS_TO]->(u:User {
|
||||
name: "${defaultAdmin.name}",
|
||||
encryptedPassword: "${defaultAdmin.password}",
|
||||
role: "admin",
|
||||
id: "${defaultAdmin.id}",
|
||||
slug: "${defaultAdmin.slug}",
|
||||
createdAt: toString(datetime()),
|
||||
allowEmbedIframes: false,
|
||||
showShoutsPublicly: false,
|
||||
emailNotificationsCommentOnObservedPost: true
|
||||
emailNotificationsPostByFollowedUser: true
|
||||
emailNotificationsPostInGroup: true
|
||||
emailNotificationsGroupMemberJoined: true
|
||||
emailNotificationsGroupMemberLeft: true
|
||||
emailNotificationsGroupMemberRemoved: true
|
||||
emailNotificationsGroupMemberRoleChanged: true
|
||||
deleted: false,
|
||||
disabled: false
|
||||
})-[:PRIMARY_EMAIL]->(e)`,
|
||||
)
|
||||
})
|
||||
try {
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
import { getDriver } from '../../db/neo4j'
|
||||
|
||||
export const description = ''
|
||||
|
||||
export async function up(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
// Implement your migration here.
|
||||
await transaction.run(`
|
||||
MATCH (user:User)
|
||||
SET user.emailNotificationsCommentOnObservedPost = user.sendNotificationEmails
|
||||
SET user.emailNotificationsPostByFollowedUser = user.sendNotificationEmails
|
||||
SET user.emailNotificationsPostInGroup = user.sendNotificationEmails
|
||||
SET user.emailNotificationsGroupMemberJoined = user.sendNotificationEmails
|
||||
SET user.emailNotificationsGroupMemberLeft = user.sendNotificationEmails
|
||||
SET user.emailNotificationsGroupMemberRemoved = user.sendNotificationEmails
|
||||
SET user.emailNotificationsGroupMemberRoleChanged = user.sendNotificationEmails
|
||||
REMOVE user.sendNotificationEmails
|
||||
`)
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
// Implement your migration here.
|
||||
await transaction.run(`
|
||||
MATCH (user:User)
|
||||
SET user.sendNotificationEmails = true
|
||||
REMOVE user.emailNotificationsCommentOnObservedPost
|
||||
REMOVE user.emailNotificationsPostByFollowedUser
|
||||
REMOVE user.emailNotificationsPostInGroup
|
||||
REMOVE user.emailNotificationsGroupMemberJoined
|
||||
REMOVE user.emailNotificationsGroupMemberLeft
|
||||
REMOVE user.emailNotificationsGroupMemberRemoved
|
||||
REMOVE user.emailNotificationsGroupMemberRoleChanged
|
||||
`)
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
@ -31,7 +31,7 @@ const queryNotificationEmails = async (context, notificationUserIds) => {
|
||||
}
|
||||
}
|
||||
|
||||
const publishNotifications = async (context, promises) => {
|
||||
const publishNotifications = async (context, promises, emailNotificationSetting: string) => {
|
||||
let notifications = await Promise.all(promises)
|
||||
notifications = notifications.flat()
|
||||
const notificationsEmailAddresses = await queryNotificationEmails(
|
||||
@ -40,7 +40,7 @@ const publishNotifications = async (context, promises) => {
|
||||
)
|
||||
notifications.forEach((notificationAdded, index) => {
|
||||
pubsub.publish(NOTIFICATION_ADDED, { notificationAdded })
|
||||
if (notificationAdded.to.sendNotificationEmails) {
|
||||
if (notificationAdded.to[emailNotificationSetting] ?? true) { // Default to true
|
||||
sendMail(
|
||||
notificationTemplate({
|
||||
email: notificationsEmailAddresses[index].email,
|
||||
@ -57,7 +57,7 @@ const handleJoinGroup = async (resolve, root, args, context, resolveInfo) => {
|
||||
if (user) {
|
||||
await publishNotifications(context, [
|
||||
notifyOwnersOfGroup(groupId, userId, 'user_joined_group', context),
|
||||
])
|
||||
], 'emailNotificationsGroupMemberJoined')
|
||||
}
|
||||
return user
|
||||
}
|
||||
@ -68,7 +68,7 @@ const handleLeaveGroup = async (resolve, root, args, context, resolveInfo) => {
|
||||
if (user) {
|
||||
await publishNotifications(context, [
|
||||
notifyOwnersOfGroup(groupId, userId, 'user_left_group', context),
|
||||
])
|
||||
], 'emailNotificationsGroupMemberLeft')
|
||||
}
|
||||
return user
|
||||
}
|
||||
@ -79,7 +79,7 @@ const handleChangeGroupMemberRole = async (resolve, root, args, context, resolve
|
||||
if (user) {
|
||||
await publishNotifications(context, [
|
||||
notifyMemberOfGroup(groupId, userId, 'changed_group_member_role', context),
|
||||
])
|
||||
], 'emailNotificationsGroupMemberRoleChanged')
|
||||
}
|
||||
return user
|
||||
}
|
||||
@ -90,7 +90,7 @@ const handleRemoveUserFromGroup = async (resolve, root, args, context, resolveIn
|
||||
if (user) {
|
||||
await publishNotifications(context, [
|
||||
notifyMemberOfGroup(groupId, userId, 'removed_user_from_group', context),
|
||||
])
|
||||
], 'emailNotificationsGroupMemberRemoved')
|
||||
}
|
||||
return user
|
||||
}
|
||||
@ -101,7 +101,7 @@ const handleContentDataOfPost = async (resolve, root, args, context, resolveInfo
|
||||
if (post) {
|
||||
await publishNotifications(context, [
|
||||
notifyUsersOfMention('Post', post.id, idsOfUsers, 'mentioned_in_post', context),
|
||||
])
|
||||
], 'TODO')
|
||||
}
|
||||
return post
|
||||
}
|
||||
@ -120,11 +120,20 @@ const handleContentDataOfComment = async (resolve, root, args, context, resolveI
|
||||
'mentioned_in_comment',
|
||||
context,
|
||||
),
|
||||
], 'TODO')
|
||||
|
||||
await publishNotifications(context, [
|
||||
notifyUsersOfComment('Comment', comment.id, 'commented_on_post', context),
|
||||
])
|
||||
], 'emailNotificationsCommentOnObservedPost')
|
||||
|
||||
return comment
|
||||
}
|
||||
|
||||
/* TODO unused
|
||||
emailNotificationsPostByFollowedUser: true
|
||||
emailNotificationsPostInGroup: true
|
||||
*/
|
||||
|
||||
const postAuthorOfComment = async (commentId, { context }) => {
|
||||
const session = context.driver.session()
|
||||
let postAuthorId
|
||||
|
||||
@ -155,10 +155,37 @@ export default {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
sendNotificationEmails: {
|
||||
|
||||
// emailNotifications
|
||||
emailNotificationsCommentOnObservedPost: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
emailNotificationsPostByFollowedUser: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
emailNotificationsPostInGroup: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
emailNotificationsGroupMemberJoined: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
emailNotificationsGroupMemberLeft: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
emailNotificationsGroupMemberRemoved: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
emailNotificationsGroupMemberRoleChanged: {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
|
||||
locale: {
|
||||
type: 'string',
|
||||
allow: [null],
|
||||
|
||||
@ -98,7 +98,13 @@ const signupCypher = (inviteCode) => {
|
||||
SET user.updatedAt = toString(datetime())
|
||||
SET user.allowEmbedIframes = false
|
||||
SET user.showShoutsPublicly = false
|
||||
SET user.sendNotificationEmails = true
|
||||
SET user.emailNotificationsCommentOnObservedPost = true
|
||||
SET user.emailNotificationsPostByFollowedUser = true
|
||||
SET user.emailNotificationsPostInGroup = true
|
||||
SET user.emailNotificationsGroupMemberJoined = true
|
||||
SET user.emailNotificationsGroupMemberLeft = true
|
||||
SET user.emailNotificationsGroupMemberRemoved = true
|
||||
SET user.emailNotificationsGroupMemberRoleChanged = true
|
||||
SET email.verifiedAt = toString(datetime())
|
||||
WITH user
|
||||
OPTIONAL MATCH (post:Post)-[:IN]->(group:Group)
|
||||
|
||||
@ -150,6 +150,30 @@ export default {
|
||||
}
|
||||
params.termsAndConditionsAgreedAt = new Date().toISOString()
|
||||
}
|
||||
|
||||
const {
|
||||
emailNotificationSettings,
|
||||
}: { emailNotificationSettings: { name: string; value: boolean }[] | undefined } = params
|
||||
if (emailNotificationSettings) {
|
||||
emailNotificationSettings.forEach((setting) => {
|
||||
const allowedSettingNames = [
|
||||
'commentOnObservedPost',
|
||||
'postByFollowedUser',
|
||||
'postInGroup',
|
||||
'groupMemberJoined',
|
||||
'groupMemberLeft',
|
||||
'groupMemberRemoved',
|
||||
'groupMemberRoleChanged',
|
||||
]
|
||||
if (!allowedSettingNames.includes(setting.name)) {
|
||||
return
|
||||
}
|
||||
params[
|
||||
'emailNotifications' + setting.name.charAt(0).toUpperCase() + setting.name.slice(1)
|
||||
] = setting.value
|
||||
})
|
||||
}
|
||||
|
||||
const session = context.driver.session()
|
||||
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
@ -355,6 +379,44 @@ export default {
|
||||
const [{ email }] = result.records.map((r) => r.get('e').properties)
|
||||
return email
|
||||
},
|
||||
emailNotificationSettings: async (parent, params, context, resolveInfo) => {
|
||||
const { user } = context
|
||||
const { id } = parent
|
||||
// Its not the own user
|
||||
if (user.id !== id) {
|
||||
return []
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
name: 'commentOnObservedPost',
|
||||
type: 'post',
|
||||
value: user.emailNotificationsCommentOnObservedPost ?? true,
|
||||
},
|
||||
{
|
||||
name: 'postByFollowedUser',
|
||||
type: 'post',
|
||||
value: user.emailNotificationsPostByFollowedUser ?? true,
|
||||
},
|
||||
{ name: 'postInGroup', type: 'post', value: user.emailNotificationsPostInGroup ?? true},
|
||||
{
|
||||
name: 'groupMemberJoined',
|
||||
type: 'group',
|
||||
value: user.emailNotificationsGroupMemberJoined ?? true,
|
||||
},
|
||||
{ name: 'groupMemberLeft', type: 'group', value: user.emailNotificationsGroupMemberLeft ?? true},
|
||||
{
|
||||
name: 'groupMemberRemoved',
|
||||
type: 'group',
|
||||
value: user.emailNotificationsGroupMemberRemoved ?? true,
|
||||
},
|
||||
{
|
||||
name: 'groupMemberRoleChanged',
|
||||
type: 'group',
|
||||
value: user.emailNotificationsGroupMemberRoleChanged ?? true,
|
||||
},
|
||||
]
|
||||
},
|
||||
...Resolver('User', {
|
||||
undefinedToNull: [
|
||||
'actorId',
|
||||
@ -366,7 +428,6 @@ export default {
|
||||
'termsAndConditionsAgreedAt',
|
||||
'allowEmbedIframes',
|
||||
'showShoutsPublicly',
|
||||
'sendNotificationEmails',
|
||||
'locale',
|
||||
],
|
||||
boolean: {
|
||||
|
||||
@ -19,6 +19,17 @@ enum _UserOrdering {
|
||||
locale_desc
|
||||
}
|
||||
|
||||
input EmailNotificationSettingsInput {
|
||||
name: String
|
||||
value: Boolean
|
||||
}
|
||||
|
||||
type EmailNotificationSettings {
|
||||
name: String
|
||||
type: String
|
||||
value: Boolean
|
||||
}
|
||||
|
||||
type User {
|
||||
id: ID!
|
||||
actorId: String
|
||||
@ -46,7 +57,7 @@ type User {
|
||||
|
||||
allowEmbedIframes: Boolean
|
||||
showShoutsPublicly: Boolean
|
||||
sendNotificationEmails: Boolean
|
||||
emailNotificationSettings: [EmailNotificationSettings]!
|
||||
locale: String
|
||||
friends: [User]! @relation(name: "FRIENDS", direction: "BOTH")
|
||||
friendsCount: Int! @cypher(statement: "MATCH (this)<-[:FRIENDS]->(r:User) RETURN COUNT(DISTINCT r)")
|
||||
@ -206,7 +217,7 @@ type Mutation {
|
||||
termsAndConditionsAgreedAt: String
|
||||
allowEmbedIframes: Boolean
|
||||
showShoutsPublicly: Boolean
|
||||
sendNotificationEmails: Boolean
|
||||
emailNotificationSettings: [EmailNotificationSettingsInput]
|
||||
locale: String
|
||||
): User
|
||||
|
||||
|
||||
@ -46,7 +46,11 @@ export const profileUserQuery = (i18n) => {
|
||||
url
|
||||
}
|
||||
showShoutsPublicly
|
||||
sendNotificationEmails
|
||||
emailNotificationSettings {
|
||||
name
|
||||
type
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -335,7 +339,7 @@ export const updateUserMutation = () => {
|
||||
$about: String
|
||||
$allowEmbedIframes: Boolean
|
||||
$showShoutsPublicly: Boolean
|
||||
$sendNotificationEmails: Boolean
|
||||
$emailNotificationSettings: [EmailNotificationSettingsInput]
|
||||
$termsAndConditionsAgreedVersion: String
|
||||
$avatar: ImageInput
|
||||
$locationName: String # empty string '' sets it to null
|
||||
@ -347,7 +351,7 @@ export const updateUserMutation = () => {
|
||||
about: $about
|
||||
allowEmbedIframes: $allowEmbedIframes
|
||||
showShoutsPublicly: $showShoutsPublicly
|
||||
sendNotificationEmails: $sendNotificationEmails
|
||||
emailNotificationSettings: $emailNotificationSettings
|
||||
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
||||
avatar: $avatar
|
||||
locationName: $locationName
|
||||
@ -359,7 +363,11 @@ export const updateUserMutation = () => {
|
||||
about
|
||||
allowEmbedIframes
|
||||
showShoutsPublicly
|
||||
sendNotificationEmails
|
||||
emailNotificationSettings {
|
||||
name
|
||||
type
|
||||
value
|
||||
}
|
||||
locale
|
||||
termsAndConditionsAgreedVersion
|
||||
avatar {
|
||||
@ -390,7 +398,11 @@ export const currentUserQuery = gql`
|
||||
locale
|
||||
allowEmbedIframes
|
||||
showShoutsPublicly
|
||||
sendNotificationEmails
|
||||
emailNotificationSettings {
|
||||
name
|
||||
type
|
||||
value
|
||||
}
|
||||
termsAndConditionsAgreedVersion
|
||||
socialMedia {
|
||||
id
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user