-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4824 from FlowFuse/invite-reminder
Send invite Reminders
- Loading branch information
Showing
10 changed files
with
273 additions
and
1 deletion.
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,15 @@ | ||
/** | ||
* Add reminderSentAt to Invitations table | ||
*/ | ||
const { DataTypes } = require('sequelize') | ||
|
||
module.exports = { | ||
up: async (context) => { | ||
await context.addColumn('Invitations', 'reminderSentAt', { | ||
type: DataTypes.DATE, | ||
allowNull: true, | ||
defaultValue: null | ||
}) | ||
}, | ||
down: async (context) => {} | ||
} |
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,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.Invitation.destroy({ where: { expiresAt: { [Op.lt]: Date.now() } } }) | ||
} | ||
} |
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 @@ | ||
const { Op } = require('sequelize') | ||
|
||
const { randomInt } = require('../utils') | ||
|
||
module.exports = { | ||
name: 'inviteReminder', | ||
startup: false, | ||
// runs daily at a randomly picked time | ||
schedule: `${randomInt(0, 59)} 6 * * *`, | ||
run: async function (app) { | ||
// need to iterate over invitations and send email to all over | ||
// 2 days old, but less than 3 days. | ||
const twoDays = new Date() | ||
twoDays.setDate(twoDays.getDate() - 2) | ||
const threeDays = new Date() | ||
threeDays.setDate(threeDays.getDate() - 3) | ||
const invites = await app.db.models.Invitation.findAll({ | ||
where: { | ||
createdAt: { | ||
[Op.between]: [threeDays, twoDays] | ||
}, | ||
reminderSentAt: { | ||
[Op.is]: null | ||
} | ||
}, | ||
include: [ | ||
{ model: app.db.models.User, as: 'invitor' }, | ||
{ model: app.db.models.User, as: 'invitee' }, | ||
{ model: app.db.models.Team, as: 'team' } | ||
] | ||
}) | ||
|
||
for (const invite of invites) { | ||
const expiryDate = invite.expiresAt.toDateString() | ||
let invitee = '' | ||
if (invite.invitee) { | ||
invitee = invite.invitee.name | ||
// 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) { | ||
invitee = 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 | ||
}) | ||
} | ||
invite.reminderSentAt = Date.now() | ||
await invite.save() | ||
|
||
// send reminder to Invitor | ||
await app.postoffice.send(invite.invitor, 'TeamInviterReminder', { | ||
teamName: invite.team.name, | ||
invitee, | ||
expiryDate | ||
}) | ||
} | ||
} | ||
} |
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,18 @@ | ||
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}}}. | ||
{{{ 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}}}.</p> | ||
<p><a href="{{{ signupLink }}}">Sign Up!</a></p> | ||
` | ||
} |
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,16 @@ | ||
module.exports = { | ||
subject: 'Invitation for {{{invitee.text}}} to {{{teamName.text}}} not accepted yet', | ||
text: | ||
` | ||
Hello, | ||
You invited {{{invitee.text}}} to join FlowFuse Team {{{teamName.text}}}, but they have not yet accepted. | ||
This invitation will expire on {{{expiryDate}}}. | ||
`, | ||
html: | ||
`<p>Hello</p> | ||
<p>You invited {{{invitee.html}}} to join FlowFuse Team {{{teamName.html}}}, but they have not yet accepted.</p> | ||
<p>This invitation will expire on {{{expiryDate}}}.</p> | ||
` | ||
} |
18 changes: 18 additions & 0 deletions
18
forge/postoffice/templates/UnknownUserInvitationReminder.js
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,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}}}. | ||
{{{ 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}}}.</p> | ||
<p><a href="{{{ signupLink }}}">Sign Up!</a></p> | ||
` | ||
} |
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