Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure pwa and add notifications #231

Merged
merged 47 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
a28a54d
Initialise pwa
Julian702 Jan 16, 2024
5f33fca
Add backend notification logic
TomRomeo Jan 17, 2024
ff65816
Fix some issues
Julian702 Jan 18, 2024
7e5e8e9
Various fixes ⚡
TomRomeo Jan 19, 2024
617460b
Adjust PushNotification model and values
Julian702 Jan 20, 2024
87451b8
Add notification check if due cards exist
TomRomeo Jan 20, 2024
1822eeb
Add plural handling for notification body
TomRomeo Jan 20, 2024
2955433
Add initial welcome notification
TomRomeo Jan 20, 2024
aa4c303
Rename notification subscribe endpoint and implement unsubscribe endp…
TomRomeo Jan 20, 2024
a5f6227
Remove unused dependency
TomRomeo Jan 20, 2024
ceaa3d8
Refactored notification sending into util function
TomRomeo Jan 24, 2024
da4a8c1
Fix welcome notification spelling
TomRomeo Jan 24, 2024
b0a36b4
Fix notification subscribe missing parameter validation
TomRomeo Jan 24, 2024
e81dece
Add get user notification subscriptions endpoint
TomRomeo Jan 24, 2024
31064bc
Add api documentation
TomRomeo Jan 24, 2024
9bba5de
Refactor backend returned response
TomRomeo Jan 25, 2024
1657119
Adjust .gitignore
Julian702 Jan 24, 2024
6ddb4ab
Add web-push and service worker
Julian702 Jan 25, 2024
901bfa0
Add frontend notification logic
Julian702 Jan 26, 2024
94609e2
Add pwa installation instruction modal
Julian702 Jan 26, 2024
9048a27
Add translations
Julian702 Jan 26, 2024
dbffa3f
Fix modal animation
Julian702 Jan 26, 2024
63cd785
Merge branch 'main' into feature/frontend/pwa
TomRomeo Jan 26, 2024
9c0f7b2
Fix build issue
Julian702 Jan 26, 2024
b03a617
Merge branch 'main' into feature/frontend/pwa
Julian702 Jan 29, 2024
921fc31
Improve InstallPWAModal
Julian702 Jan 29, 2024
141f8f8
Implement PR feedback
TomRomeo Jan 29, 2024
a374365
Apply pr feedback
Julian702 Jan 29, 2024
2a3ba4b
Implement PR feedback
TomRomeo Jan 29, 2024
92a0563
Apply more pr feedback
Julian702 Jan 29, 2024
ac30cc3
Apply even more pr feedback
Julian702 Jan 30, 2024
8e13e28
Fixed some minor issues
TomRomeo Jan 30, 2024
866596d
Missing continue
TomRomeo Jan 31, 2024
8ae36e9
Fix some last issues
Julian702 Jan 31, 2024
5998ee8
Fix plural selection logic
TomRomeo Jan 31, 2024
ec681d1
Refactor notification times to a practical value
TomRomeo Jan 31, 2024
f254f69
Implement PR feedback
TomRomeo Jan 31, 2024
1bac568
Add return type for get subscriptions
TomRomeo Jan 31, 2024
1c0813c
Apply pr feedback
Julian702 Jan 31, 2024
022dd3e
Revert dockerfile changes
TomRomeo Jan 31, 2024
fb18831
Adjust frontend
Julian702 Jan 31, 2024
14762a7
Apply pr feedback
Julian702 Jan 31, 2024
4c4ba0f
Add notification service to github workflows
TomRomeo Jan 31, 2024
19da125
Implement PR feedback
TomRomeo Feb 1, 2024
dc16e28
Added context to function call
TomRomeo Feb 1, 2024
a02ec9e
Adapt Helm Chart
memeToasty Feb 1, 2024
0bc228e
Renamed `notifications` to `notification`
memeToasty Feb 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/notification_service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Notification Service

on:
pull_request:
branches: [ main ]
paths:
- 'backend/services/notification/**'
- 'backend/store/**'

jobs:
build-notification:
uses: ./.github/workflows/build_service.yml
with:
image-name: kioku_notification
path: ./backend/services/notification
context: ./backend
9 changes: 8 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,11 @@ jobs:
image-name: kioku_srs
image-tag: prod
path: ./backend/services/srs
context: ./backend
context: ./backend
build-notification:
uses: ./.github/workflows/build_service.yml
with:
image-name: kioku_notification
image-tag: prod
path: ./backend/services/notification
context: ./backend
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@
*secret.yaml
private_key.yaml
.DS_STORE
frontend/build-storybook.log
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ You can generate the `JWT_PRIVATE_KEY` with the following command
openssl ecparam -name secp521r1 -genkey -noout -out my.key.pem
```

To enable notification support, you will have to generate a VAPID keypair and add the public and private key to the frontend and backend `.env` files.
To do this, you can type the following command in the frontend folder:
```bash
npx web-push generate-vapid-keys
```

> [!WARNING]
> The example environment file is populated with default values, be sure to change all values before using the application in production!

Expand Down
2 changes: 2 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ TRACING_ENABLED=false
JWT_PRIVATE_KEY="
# generate with: `openssl ecparam -name secp521r1 -genkey -noout -out my.key.pem`
"
VAPID_PUBLIC_KEY=""
VAPID_PRIVATE_KEY=""
4KevR marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion backend/api-documentation/user/delete user.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: delete user
type: http
seq: 7
seq: 9
}

delete {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
meta {
name: get notification subscriptions
type: http
seq: 4
}

get {
url: {{baseUrl}}/api/user/notification
body: json
auth: bearer
}

auth:bearer {
token: {{accessToken}}
}

body:json {
{
"endpoint": "",
"auth": "",
"p256dh": ""
}
}
2 changes: 1 addition & 1 deletion backend/api-documentation/user/modify user.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: modify user
type: http
seq: 6
seq: 8
}

put {
Expand Down
2 changes: 1 addition & 1 deletion backend/api-documentation/user/register.bru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
meta {
name: register
type: http
seq: 4
seq: 6
}

post {
Expand Down
23 changes: 23 additions & 0 deletions backend/api-documentation/user/subscribe notifications.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
meta {
name: subscribe notifications
type: http
seq: 7
}

post {
url: {{baseUrl}}/api/user/notification
body: json
auth: bearer
}

auth:bearer {
token: {{accessToken}}
}

body:json {
{
"endpoint": "",
"auth": "",
"p256dh": ""
}
}
15 changes: 15 additions & 0 deletions backend/api-documentation/user/unsubscribe notifications.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
meta {
name: unsubscribe notifications
type: http
seq: 10
}

delete {
url: {{baseUrl}}/api/user/notification/{{subscriptionID}}
body: none
auth: bearer
}

auth:bearer {
token: {{accessToken}}
}
3 changes: 3 additions & 0 deletions backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ module github.com/kioku-project/kioku
go 1.20

require (
github.com/SherClockHolmes/webpush-go v1.3.0
github.com/go-micro/plugins/v4/client/grpc v1.2.1
github.com/go-micro/plugins/v4/registry/kubernetes v1.1.2
github.com/go-micro/plugins/v4/server/grpc v1.2.0
github.com/gofiber/fiber/v2 v2.52.0
github.com/gofiber/jwt/v3 v3.3.10
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/joho/godotenv v1.5.1
github.com/robfig/cron/v3 v3.0.0
go-micro.dev/v4 v4.10.2
go.opentelemetry.io/otel v1.22.0
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
Expand All @@ -25,6 +27,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
Expand Down
10 changes: 10 additions & 0 deletions backend/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/SherClockHolmes/webpush-go v1.3.0 h1:CAu3FvEE9QS4drc3iKNgpBWFfGqNthKlZhp5QpYnu6k=
github.com/SherClockHolmes/webpush-go v1.3.0/go.mod h1:AxRHmJuYwKGG1PVgYzToik1lphQvDnqFYDqimHvwhIw=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
Expand Down Expand Up @@ -72,6 +74,8 @@ github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/
github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/gofiber/jwt/v3 v3.3.10 h1:0bpWtFKaGepjwYTU4efHfy0o+matSqZwTxGMo5a+uuc=
github.com/gofiber/jwt/v3 v3.3.10/go.mod h1:GJorFVaDyfMPSK9RB8RG4NQ3s1oXKTmYaoL/ny08O1A=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
Expand Down Expand Up @@ -146,6 +150,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron/v3 v3.0.0 h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E=
github.com/robfig/cron/v3 v3.0.0/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand Down Expand Up @@ -214,6 +220,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
Expand All @@ -234,6 +241,7 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -268,6 +276,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand All @@ -277,6 +286,7 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
4 changes: 4 additions & 0 deletions backend/pkg/converter/fiberSerializerTypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,7 @@ type FiberGetGroupMemberRequestsResponseBody struct {
type FiberGetInvitationsForGroupResponseBody struct {
MemberRequests []FiberGroupMemberAdmission `json:"groupInvitations"`
}

type FiberGetUserSubscriptionsResponseBody struct {
UserSubscriptions []string `json:"userSubscriptions"`
}
13 changes: 13 additions & 0 deletions backend/pkg/converter/typeConverter.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,16 @@ func ProtoUserWithRoleToFiberGroupMember(groupMembers *pbCommon.User) FiberGroup
GroupRole: groupMembers.GroupRole.String(),
}
}

func StoreNotificationSubscriptionToProtoNotificationSubscriptionConverter(subscription *model.PushSubscription) *pbCommon.PushSubscription {
return &pbCommon.PushSubscription{
SubscriptionID: subscription.ID,
Endpoint: subscription.Endpoint,
P256Dh: subscription.P256DH,
Auth: subscription.Auth,
}
}

func ProtoNotificationSubscriptionToIDStringConverter(subscription *pbCommon.PushSubscription) string {
return subscription.SubscriptionID
}
1 change: 1 addition & 0 deletions backend/pkg/helper/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
FrontendServiceID ClientID = "services.frontend"
UserServiceID ClientID = "services.user"
SrsServiceID ClientID = "services.srs"
NotificationServiceID ClientID = "services.notification"
)

var (
Expand Down
10 changes: 10 additions & 0 deletions backend/pkg/helper/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package helper

func SomeEmpty(fields ...string) bool {
for _, field := range fields {
if field == "" {
return true
}
}
return false
}
34 changes: 34 additions & 0 deletions backend/pkg/model/notification.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package model

import gorm "gorm.io/gorm"
import "github.com/kioku-project/kioku/pkg/helper"

type PushNotification struct {
Title string `json:"title"`
Options PushNotificationOptions `json:"options"`
}

type PushNotificationOptions struct {
Body string `json:"body"`
Actions []map[string]string `json:"actions"`
TomRomeo marked this conversation as resolved.
Show resolved Hide resolved
Vibrate []int `json:"vibrate"`
Tag string `json:"tag"`
}

type PushSubscription struct {
ID string `gorm:"primaryKey"`
UserID string `gorm:"not null"`
User User
Endpoint string `gorm:"not null"`
P256DH string `gorm:"not null"`
Auth string `gorm:"not null"`
}

func (c *PushSubscription) BeforeCreate(db *gorm.DB) (err error) {
newID, err := helper.FindFreeID(db, 10, func() (helper.PublicID, *PushSubscription) {
id := helper.GenerateID('N')
return id, &PushSubscription{ID: id.GetStringRepresentation()}
})
c.ID = newID.GetStringRepresentation()
return
}
TomRomeo marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading