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

Allow optional signature when registering notifications #1797

Merged
merged 48 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
313269c
Add migration for notifications
iamacook Jul 11, 2024
82e755b
Rename token column
iamacook Jul 12, 2024
be971ab
Add `cloud_messaging_token` <> `PUSH_NOTIFICATIONS` medium constraints
iamacook Jul 12, 2024
3fa4b2f
Cleanup test
iamacook Jul 12, 2024
2a356cf
Remove `enabled` column and triggers
iamacook Jul 17, 2024
6193c4f
Add `device_uuid` column
iamacook Jul 17, 2024
dc736e7
Rename `medium` to `channel`
iamacook Jul 17, 2024
aa939ff
Add datasource for notifications
iamacook Jul 22, 2024
422c719
Fix tests
iamacook Jul 22, 2024
6c33fa5
Improve datasource tests
iamacook Jul 22, 2024
107b7da
Merge branch 'main' into notifications-database
iamacook Jul 22, 2024
4e10a90
Fix types
iamacook Jul 22, 2024
8eddd84
Get subscribers with their tokens
iamacook Jul 22, 2024
a644d71
Merge branch 'main' into notifications-database
iamacook Jul 22, 2024
bbf8872
Fix lint and tests
iamacook Jul 23, 2024
906e7b6
Facilitate multiple Safe notifications across devices
iamacook Jul 24, 2024
1db3af7
Remove unnecessary `account_id` from `notification_devices` table
iamacook Jul 24, 2024
bab3f52
Remove unused entities
iamacook Jul 24, 2024
1990006
Merge channel/device tables and move orphan logic to domain
iamacook Jul 24, 2024
e59bf08
Add domain logic for push notifications
iamacook Jul 22, 2024
a73958b
Fix test
iamacook Jul 23, 2024
4d5bd6e
Add feature flag for push notifications
iamacook Jul 23, 2024
6658f68
Only call enqueuer if feature enabled
iamacook Jul 23, 2024
ec8b9c6
Fix interfaces
iamacook Jul 24, 2024
86de998
Cleanup unregistered tokens
iamacook Jul 24, 2024
b59e7f7
Fix tests and cleanup stale tokens
iamacook Jul 24, 2024
b9354c9
Fix query
iamacook Jul 24, 2024
8088fcd
Simplify upsertion logic
iamacook Jul 25, 2024
663d901
Add log and test coverage
iamacook Jul 27, 2024
c63bf4a
Decouple account from notifications
iamacook Jul 30, 2024
8badc91
Decouple notifications from account in datasource
iamacook Jul 30, 2024
2d2ab0d
Move datasource
iamacook Jul 30, 2024
700e552
Merge branch 'main' into notifications-database
iamacook Jul 30, 2024
1ea77f3
Merge branch 'notifications-database' into notifications-domain
iamacook Jul 30, 2024
c908fae
Remove unnecessary entity and fix typos
iamacook Jul 30, 2024
c13f4b8
Dispatch notifications on hook
iamacook Jul 31, 2024
f408883
Add notifications routes
iamacook Jul 25, 2024
a1095d4
Add further test coverage
iamacook Jul 25, 2024
62e64b6
Assert errors are forwarded by datasource
iamacook Jul 25, 2024
71a8cb8
Add `JwtConfigurationModule` override
iamacook Jul 26, 2024
5893e6f
Use test configuration
iamacook Jul 26, 2024
f18abc1
Fix tests
iamacook Jul 27, 2024
e970dc0
Fix tests
iamacook Jul 31, 2024
26f76b4
Remove comment
iamacook Jul 31, 2024
74b30b9
Allow optional signature when registering notifications
iamacook Aug 1, 2024
da026fe
Expect `signerAddress` for preference retrieval
iamacook Aug 1, 2024
7875a51
Merge branch 'main' into notifications-optional-signature
iamacook Aug 7, 2024
da9bf55
Address comments
iamacook Aug 19, 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
2 changes: 1 addition & 1 deletion migrations/00005_notifications/index.sql
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ CREATE TABLE notification_subscriptions (
push_notification_device_id INT NOT NULL,
chain_id VARCHAR(255) NOT NULL,
safe_address VARCHAR(42) NOT NULL,
signer_address VARCHAR(42) NOT NULL,
signer_address VARCHAR(42),
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
FOREIGN KEY (push_notification_device_id) REFERENCES push_notification_devices(id) ON DELETE CASCADE,
Expand Down
38 changes: 36 additions & 2 deletions migrations/__tests__/00005_notifications.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type NotificationTypesRow = {

type NotificationSubscriptionsRow = {
id: number;
signer_address: `0x${string}`;
signer_address: `0x${string}` | null;
push_notification_device_id: PushNotificationDevicesRow['id'];
chain_id: string;
safe_address: `0x${string}`;
Expand Down Expand Up @@ -302,6 +302,40 @@ describe('Migration 00005_notifications', () => {
).resolves.toStrictEqual([]);
});

it('should allow nullable signer_address in notification_subscriptions', async () => {
const safeAddress = getAddress(faker.finance.ethereumAddress());
const chainId = faker.string.numeric();
const deviceType = faker.helpers.arrayElement(Object.values(DeviceType));
const deviceUuid = faker.string.uuid() as UUID;
const cloudMessagingToken = faker.string.alphanumeric();
const afterMigration = await migrator.test({
migration: '00005_notifications',
after: (sql: postgres.Sql) => {
// Create device
return sql<
[PushNotificationDevicesRow]
>`INSERT INTO push_notification_devices (device_type, device_uuid, cloud_messaging_token) VALUES (${deviceType}, ${deviceUuid}, ${cloudMessagingToken}) RETURNING *`;
},
});

// Create subscription
await expect(
sql<
[NotificationSubscriptionsRow]
>`INSERT INTO notification_subscriptions (push_notification_device_id, chain_id, safe_address) VALUES (${afterMigration.after[0].id}, ${chainId}, ${safeAddress}) RETURNING *`,
).resolves.toStrictEqual([
{
id: 1,
signer_address: null,
push_notification_device_id: afterMigration.after[0].id,
chain_id: chainId,
safe_address: safeAddress,
created_at: expect.any(Date),
updated_at: expect.any(Date),
},
]);
});

it('should prevent duplicate subscriptions (signer, chain, Safe address and device) in notification_subscriptions', async () => {
const signerAddress = getAddress(faker.finance.ethereumAddress());
const safeAddress = getAddress(faker.finance.ethereumAddress());
Expand All @@ -325,7 +359,7 @@ describe('Migration 00005_notifications', () => {

// Create duplicate subscription
await expect(
sql`INSERT INTO notification_subscriptions (signer_address, push_notification_device_id, chain_id, safe_address) VALUES (${afterMigration.after[0].signer_address}, ${afterMigration.after[0].push_notification_device_id}, ${chainId}, ${safeAddress})`,
sql`INSERT INTO notification_subscriptions (signer_address, push_notification_device_id, chain_id, safe_address) VALUES (${signerAddress}, ${afterMigration.after[0].push_notification_device_id}, ${chainId}, ${safeAddress})`,
).rejects.toThrow(
'duplicate key value violates unique constraint "notification_subscriptions_chain_id_safe_address_push_notif_key"',
);
Expand Down
Loading
Loading