[server] Send email when link is joined

This commit is contained in:
Neeraj Gupta
2025-01-07 11:44:22 +05:30
parent 167d2c5d29
commit 9e901c78ef
5 changed files with 206 additions and 26 deletions

View File

@@ -5,11 +5,6 @@ import (
"database/sql"
b64 "encoding/base64"
"fmt"
"github.com/ente-io/museum/ente/base"
"github.com/ente-io/museum/pkg/controller/emergency"
"github.com/ente-io/museum/pkg/controller/file_copy"
"github.com/ente-io/museum/pkg/controller/filedata"
emergencyRepo "github.com/ente-io/museum/pkg/repo/emergency"
"net/http"
"os"
"os/signal"
@@ -19,6 +14,12 @@ import (
"syscall"
"time"
"github.com/ente-io/museum/ente/base"
"github.com/ente-io/museum/pkg/controller/emergency"
"github.com/ente-io/museum/pkg/controller/file_copy"
"github.com/ente-io/museum/pkg/controller/filedata"
emergencyRepo "github.com/ente-io/museum/pkg/repo/emergency"
"github.com/ente-io/museum/pkg/repo/two_factor_recovery"
"github.com/ente-io/museum/pkg/controller/cast"
@@ -305,6 +306,7 @@ func main() {
collectionController := &controller.CollectionController{
CollectionRepo: collectionRepo,
EmailCtrl: emailNotificationCtrl,
AccessCtrl: accessCtrl,
PublicCollectionCtrl: publicCollectionCtrl,
UserRepo: userRepo,

View File

@@ -0,0 +1,139 @@
{{define "base"}}
<!DOCTYPE html>
<html>
<meta content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1,
minimum-scale=1" />
<style>
body {
background-color: #f0f1f3;
font-family: "Helvetica Neue", "Segoe UI", Helvetica, sans-serif;
font-size: 16px;
line-height: 27px;
margin: 0;
color: #444;
}
pre {
background: #f4f4f4f4;
padding: 2px;
}
table {
width: 100%;
border: 1px solid #ddd;
}
table td {
border-color: #ddd;
padding: 5px;
}
.wrap {
background-color: #fff;
padding: 30px;
max-width: 525px;
margin: 0 auto;
border-radius: 5px;
}
.button {
background: #0055d4;
border-radius: 3px;
text-decoration: none !important;
color: #fff !important;
font-weight: bold;
padding: 10px 30px;
display: inline-block;
}
.button:hover {
background: #111;
}
.footer {
text-align: center;
font-size: 12px;
color: #888;
}
.footer a {
color: #888;
margin-right: 5px;
}
.gutter {
padding: 30px;
}
img {
max-width: 100%;
height: auto;
}
a {
color: #0055d4;
}
a:hover {
color: #111;
}
@media screen and (max-width: 600px) {
.wrap {
max-width: auto;
}
.gutter {
padding: 10px;
}
}
.footer-icons {
padding: 4px !important;
width: 24px !important;
}
</style>
<body>
<div class="gutter" style="padding: 4px">&nbsp;</div>
<div class="wrap" style=" background-color: rgb(255, 255, 255); padding: 2px
30px 30px 30px; max-width: 525px; margin: 0 auto; border-radius: 5px;
font-size: 16px; " >
<main>
{{block "content" .}} Default Content {{end}}
</main>
</div>
<br />
<div class="footer" style="text-align: center; font-size: 12px; color:
rgb(136, 136, 136)" >
<div>
<a href="https://ente.io" target="_blank" ><img
src="https://email-assets.ente.io/ente-green.png" style="width: 100px;
padding: 24px" title="Ente" alt="Ente" /></a>
</div>
<div>
<a href="https://fosstodon.org/@ente" target="_blank" ><img
src="https://email-assets.ente.io/mastodon-icon.png"
class="footer-icons" style="width: 24px; padding: 4px" title="Mastodon"
alt="Mastodon" /></a>
<a href="https://twitter.com/enteio" target="_blank" ><img
src="https://email-assets.ente.io/twitter-icon.png" class="footer-icons"
style="width: 24px; padding: 4px" title="Twitter" alt="Twitter" /></a>
<a href="https://discord.ente.io" target="_blank" ><img
src="https://email-assets.ente.io/discord-icon.png" class="footer-icons"
style="width: 24px; padding: 4px" title="Discord" alt="Discord" /></a>
<a href="https://github.com/ente-io" target="_blank" ><img
src="https://email-assets.ente.io/github-icon.png" class="footer-icons"
style="width: 24px; padding: 4px" title="GitHub" alt="GitHub" /></a>
</div>
<p>
Ente Technologies, Inc.
<br /> 1111B S Governors Ave 6032 Dover, DE 19904
</p>
<br />
</div>
</body>
</html>
{{end}}

View File

@@ -0,0 +1,9 @@
{{define "content"}}
<p>Hello,</p>
<p> {{.OtherUserEmail}} has joined your album via a public link. </p>
<p>You can revoke access or change permissions for {{.OtherUserEmail}} from the Ente app. </p>
<p> For any assistance or questions, please reply to this email. </p>
{{end}}

View File

@@ -4,11 +4,13 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/ente-io/museum/pkg/repo/cast"
"runtime/debug"
"strings"
"github.com/ente-io/museum/pkg/repo/cast"
"github.com/ente-io/museum/pkg/controller/access"
"github.com/ente-io/museum/pkg/controller/email"
"github.com/gin-contrib/requestid"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
@@ -31,6 +33,7 @@ const (
// CollectionController encapsulates logic that deals with collections
type CollectionController struct {
PublicCollectionCtrl *PublicCollectionController
EmailCtrl *email.EmailNotificationController
AccessCtrl access.Controller
BillingCtrl *BillingController
CollectionRepo *repo.CollectionRepository
@@ -219,7 +222,12 @@ func (c *CollectionController) JoinViaLink(ctx *gin.Context, req ente.JoinCollec
if publicCollectionToken.EnableCollect {
role = ente.COLLABORATOR
}
return c.CollectionRepo.Share(req.CollectionID, collection.Owner.ID, userID, req.EncryptedKey, role, time.Microseconds())
joinErr := c.CollectionRepo.Share(req.CollectionID, collection.Owner.ID, userID, req.EncryptedKey, role, time.Microseconds())
if joinErr != nil {
return stacktrace.Propagate(joinErr, "")
}
go c.EmailCtrl.OnLinkJoined(collection.Owner.ID, userID, role)
return nil
}
// UnShare unshares a collection with a user

View File

@@ -5,6 +5,7 @@ import (
"strconv"
"github.com/avct/uasurfer"
"github.com/ente-io/museum/ente"
"github.com/ente-io/museum/pkg/controller/lock"
"github.com/ente-io/museum/pkg/repo"
"github.com/ente-io/museum/pkg/utils/email"
@@ -13,31 +14,31 @@ import (
)
const (
WebAppFirstUploadTemplate = "web_app_first_upload.html"
MobileAppFirstUploadTemplate = "mobile_app_first_upload.html"
FirstUploadEmailSubject = "Congratulations! 🎉"
StorageLimitExceededMailLock = "storage_limit_exceeded_mail_lock"
StorageLimitExceededTemplateID = "storage_limit_exceeded"
StorageLimitExceededTemplate = "storage_limit_exceeded.html"
FilesCollectedTemplate = "files_collected.html"
FilesCollectedTemplateID = "files_collected"
FilesCollectedSubject = "You've got photos!"
WebAppFirstUploadTemplate = "web_app_first_upload.html"
MobileAppFirstUploadTemplate = "mobile_app_first_upload.html"
FirstUploadEmailSubject = "Congratulations! 🎉"
StorageLimitExceededMailLock = "storage_limit_exceeded_mail_lock"
StorageLimitExceededTemplateID = "storage_limit_exceeded"
StorageLimitExceededTemplate = "storage_limit_exceeded.html"
FilesCollectedTemplate = "files_collected.html"
FilesCollectedTemplateID = "files_collected"
FilesCollectedSubject = "You've got photos!"
SubscriptionUpgradedTemplate = "subscription_upgraded.html"
SubscriptionUpgradedSubject = "Thank you for choosing Ente!"
SubscriptionUpgradedTemplate = "subscription_upgraded.html"
SubscriptionUpgradedSubject = "Thank you for choosing Ente!"
SubscriptionCancelledSubject = "Good bye (?) from Ente"
SubscriptionCancelledTemplate = "subscription_cancelled.html"
FilesCollectedMuteDurationInMinutes = 10
StorageLimitExceededSubject = "[Alert] You have exceeded your storage limit"
ReferralSuccessfulTemplate = "successful_referral.html"
ReferralSuccessfulSubject = "You've earned 10 GB on Ente! 🎁"
StorageLimitExceededSubject = "[Alert] You have exceeded your storage limit"
ReferralSuccessfulTemplate = "successful_referral.html"
ReferralSuccessfulSubject = "You've earned 10 GB on Ente! 🎁"
LoginSuccessSubject = "New login to your Ente account"
LoginSuccessTemplate = "on_login.html"
LoginSuccessSubject = "New login to your Ente account"
LoginSuccessTemplate = "on_login.html"
)
type EmailNotificationController struct {
@@ -78,6 +79,27 @@ func (c *EmailNotificationController) OnSuccessfulReferral(userID int64) {
}
}
func (c *EmailNotificationController) OnLinkJoined(ownerID int64, otherUserID int64, role ente.CollectionParticipantRole) {
user, err := c.UserRepo.Get(ownerID)
if err != nil {
return
}
otherUser, err := c.UserRepo.Get(otherUserID)
if err != nil {
return
}
data := map[string]interface{}{
"OtherUserEmail": otherUser.Email,
"Role": role,
}
err = email.SendTemplatedEmailV2(
[]string{user.Email}, "Ente", "team@ente.io",
fmt.Sprintf("%s has joined your album", otherUser.Email), "base.html", "on_link_joined.html", data, nil)
if err != nil {
log.Error("Error sending link joined email ", err)
}
}
func (c *EmailNotificationController) OnFilesCollected(userID int64) {
user, err := c.UserRepo.Get(userID)
if err != nil {