Skip to content

Commit

Permalink
Send invite Reminders
Browse files Browse the repository at this point in the history
part of #4380
  • Loading branch information
hardillb committed Nov 22, 2024
1 parent ffa0555 commit 175be7c
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 0 deletions.
2 changes: 2 additions & 0 deletions forge/housekeeper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ module.exports = fp(async function (app, _opts) {
await registerTask(require('./tasks/licenseOverage'))
await registerTask(require('./tasks/telemetryMetrics'))
await registerTask(require('./tasks/teamBroker'))
await registerTask(require('./tasks/expireInvites'))
await registerTask(require('./tasks/inviteReminder'))

app.addHook('onReady', async () => {
let promise = Promise.resolve()
Expand Down
14 changes: 14 additions & 0 deletions forge/housekeeper/tasks/expireInvites.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const { Op } = require('sequelize')

const { randomInt } = require('../utils')

module.exports = {
name: 'expiredInvites',
startup: true,
// Pick a random hour/minute for this task to run at. If the application is
// horizontal scaled, this will avoid two instances running at the same time
schedule: `${randomInt(0, 59)} ${randomInt(0, 23)} * * *`,
run: async function (app) {
await app.db.models.Invites.destroy({ where : {expiresAt: { [Op.lt]: Date.now() } } })

Check failure on line 12 in forge/housekeeper/tasks/expireInvites.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

Extra space after key 'where'

Check failure on line 12 in forge/housekeeper/tasks/expireInvites.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

A space is required after '{'
}
}

Check failure on line 14 in forge/housekeeper/tasks/expireInvites.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

Newline required at end of file but not found
64 changes: 64 additions & 0 deletions forge/housekeeper/tasks/inviteReminder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const { Op } = require('sequelize')

const { randomInt } = require('../utils')

Check failure on line 3 in forge/housekeeper/tasks/inviteReminder.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

'randomInt' is assigned a value but never used

module.exports = {
name: 'inviteReminder',
startup: false,
// This fixed time will not work well when horizontal scaling
// will need to find a way to pick a "leader"
schedule: `38 3 * * *`,

Check failure on line 10 in forge/housekeeper/tasks/inviteReminder.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

Strings must use singlequote
run: async function (app) {
try {
// need to iterate over invitations and send email to all over

Check failure on line 13 in forge/housekeeper/tasks/inviteReminder.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

Trailing spaces not allowed
// 2 days old, but less than 3 days.
const twoDays = new Date()

Check failure on line 15 in forge/housekeeper/tasks/inviteReminder.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

Expected indentation of 12 spaces but found 8
twoDays.setDate(twoDays.getDate() - 2)

Check failure on line 16 in forge/housekeeper/tasks/inviteReminder.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

Expected indentation of 12 spaces but found 8
const threeDays = new Date()

Check failure on line 17 in forge/housekeeper/tasks/inviteReminder.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

Expected indentation of 12 spaces but found 8
threeDays.setDate(threeDays.getDate() - 3)

Check failure on line 18 in forge/housekeeper/tasks/inviteReminder.js

View workflow job for this annotation

GitHub Actions / Postgres tests (18.x)

Expected indentation of 12 spaces but found 8
console.log(twoDays.toISOString(), threeDays.toISOString())
const invites = await app.db.models.Invitation.findAll({
where: {
createdAt: {
[Op.between]: [threeDays, twoDays]
}
},
include: [
{ model: app.db.models.User, as: 'invitor'},
{ model: app.db.models.User, as: 'invitee'}
]
})


for(const invite of invites) {
const expiryDate = invite.expiresAt.toDateString()
if (invite.invitee) {
// Existing user
await app.postoffice.send(invite.invitee, 'TeamInviteReminder',{
teamName: invite.team.name,
signupLink: `${app.config.base_url}/account/teams/invitations`,
expiryDate
})
} else if (invite.email) {
// External user
let signupLink = `${app.config.base_url}/account/create?email=${encodeURIComponent(invite.email)}`
if (app.license.active()) {
// Check if this is for an SSO-enabled domain with auto-create turned on
const providerConfig = await app.db.models.SAMLProvider.forEmail(invite.email)
if (providerConfig?.options?.provisionNewUsers) {
signupLink = `${app.config.base_url}`
}
}

await app.postoffice.send(invite, 'UnknownUserInvitationReminder', {
invite,
signupLink,
expiryDate
})
}
}
} catch (err) {
console.log(err)
}
}
}
20 changes: 20 additions & 0 deletions forge/postoffice/templates/TeamInviteReminder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const { subject } = require("./TeamInvitation");

module.exports = {
subject: 'Invitation to join team {{{teamName.text}}} on FlowFuse',
text:
`Hello!
This is a reminder that you have an invite to join team {{{teamName.text}}} on the FlowFuse platform.
This invitation will expire on {{{expiryDate.text}}}.
{{{ signupLink }}}
`,
html:
`<p>Hello!</p>
<p>You've been invited to join team {{{teamName.html}}} on the FlowFuse platform.</p>
<p>This invitation will expire on {{{expiryDate.html}}}.</p>
<p><a href="{{{ signupLink }}}">Sign Up!</a></p>
`
}
18 changes: 18 additions & 0 deletions forge/postoffice/templates/UnknownUserInvitationReminder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
subject: 'Invitation to collaborate on FlowFuse',
text:
`Hello!
This is quick reminder that you've been invited to join the FlowFuse platform. Use the link below to sign-up and get started.
This invitation will expire on {{{expiryDate.text}}}.
{{{ signupLink }}}
`,
html:
`<p>Hello!</p>
<p>This is quick reminder that you've been invited to join the FlowFuse platform. Use the link below to sign-up and get started.</p>
<p>This invitation will expire on {{{expiryDate.html}}}.</p>
<p><a href="{{{ signupLink }}}">Sign Up!</a></p>
`
}

0 comments on commit 175be7c

Please sign in to comment.