From 334d9e91c2dcfe759bbe1318e3d3b17e714b4ec6 Mon Sep 17 00:00:00 2001
From: Ariel Gentile
Date: Sat, 5 Aug 2023 11:01:50 -0300
Subject: [PATCH 1/2] fix(push-notifications)!: align to RFCs 0699/0734
Signed-off-by: Ariel Gentile
---
packages/push-notifications/README.md | 2 +-
.../src/apns/PushNotificationsApnsApi.ts | 5 +-
.../src/apns/PushNotificationsApnsModule.ts | 16 +-
.../src/apns/PushNotificationsApnsService.ts | 5 +-
...PushNotificationsApnsProblemReportError.ts | 30 ++++
...ushNotificationsApnsProblemReportReason.ts | 11 ++
.../src/apns/errors/index.ts | 2 +
...shNotificationsApnsProblemReportHandler.ts | 18 ++
.../src/apns/handlers/index.ts | 1 +
.../PushNotificationsApnsDeviceInfoMessage.ts | 9 +-
...shNotificationsApnsGetDeviceInfoMessage.ts | 2 +-
...shNotificationsApnsProblemReportMessage.ts | 23 +++
...shNotificationsApnsSetDeviceInfoMessage.ts | 7 +-
.../src/apns/messages/index.ts | 1 +
.../src/apns/models/ApnsDeviceInfo.ts | 2 +-
.../apns/models/PushNotificationsApnsRole.ts | 10 ++
.../src/apns/models/index.ts | 1 +
.../src/fcm/PushNotificationsFcmApi.ts | 5 +-
.../src/fcm/PushNotificationsFcmModule.ts | 16 +-
.../src/fcm/PushNotificationsFcmService.ts | 35 +++-
.../PushNotificationsFcmProblemReportError.ts | 30 ++++
...PushNotificationsFcmProblemReportReason.ts | 11 ++
.../src/fcm/errors/index.ts | 2 +
...ushNotificationsFcmProblemReportHandler.ts | 18 ++
...ushNotificationsFcmSetDeviceInfoHandler.ts | 8 +-
.../src/fcm/handlers/index.ts | 1 +
.../PushNotificationsFcmDeviceInfoMessage.ts | 15 +-
...ushNotificationsFcmGetDeviceInfoMessage.ts | 2 +-
...ushNotificationsFcmProblemReportMessage.ts | 23 +++
...ushNotificationsFcmSetDeviceInfoMessage.ts | 13 +-
.../src/fcm/messages/index.ts | 1 +
.../src/fcm/models/FcmDeviceInfo.ts | 3 +-
.../fcm/models/PushNotificationsFcmRole.ts | 10 ++
.../src/fcm/models/index.ts | 1 +
.../pushNotificationsApnsService.test.ts | 18 +-
.../tests/pushNotificationsFcmService.test.ts | 156 ++++++++++++++++--
36 files changed, 464 insertions(+), 49 deletions(-)
create mode 100644 packages/push-notifications/src/apns/errors/PushNotificationsApnsProblemReportError.ts
create mode 100644 packages/push-notifications/src/apns/errors/PushNotificationsApnsProblemReportReason.ts
create mode 100644 packages/push-notifications/src/apns/errors/index.ts
create mode 100644 packages/push-notifications/src/apns/handlers/PushNotificationsApnsProblemReportHandler.ts
create mode 100644 packages/push-notifications/src/apns/messages/PushNotificationsApnsProblemReportMessage.ts
create mode 100644 packages/push-notifications/src/apns/models/PushNotificationsApnsRole.ts
create mode 100644 packages/push-notifications/src/fcm/errors/PushNotificationsFcmProblemReportError.ts
create mode 100644 packages/push-notifications/src/fcm/errors/PushNotificationsFcmProblemReportReason.ts
create mode 100644 packages/push-notifications/src/fcm/errors/index.ts
create mode 100644 packages/push-notifications/src/fcm/handlers/PushNotificationsFcmProblemReportHandler.ts
create mode 100644 packages/push-notifications/src/fcm/messages/PushNotificationsFcmProblemReportMessage.ts
create mode 100644 packages/push-notifications/src/fcm/models/PushNotificationsFcmRole.ts
diff --git a/packages/push-notifications/README.md b/packages/push-notifications/README.md
index 974f0787..a99bb493 100644
--- a/packages/push-notifications/README.md
+++ b/packages/push-notifications/README.md
@@ -28,6 +28,6 @@
-Push Notifications plugin for [Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript.git).
+Push Notifications extension module for [Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript.git). It currently implements [Aries RFC 0734](https://github.com/hyperledger/aries-rfcs/tree/main/features/0734-push-notifications-fcm) (Firebase Cloud Messaging) and [Aries RFC 0699](https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns) (Apple Push Notifications).
For documentation on installation and usage of the Push Notifications package, refer to the [Docs](https://aries.js.org/guides/0.4/extensions/push-notifications).
diff --git a/packages/push-notifications/src/apns/PushNotificationsApnsApi.ts b/packages/push-notifications/src/apns/PushNotificationsApnsApi.ts
index 7615b23b..e6e639db 100644
--- a/packages/push-notifications/src/apns/PushNotificationsApnsApi.ts
+++ b/packages/push-notifications/src/apns/PushNotificationsApnsApi.ts
@@ -53,14 +53,15 @@ export class PushNotificationsApnsApi {
* Response for `push-notifications-apns/get-device-info`
*
* @param connectionId The connection ID string
+ * @param threadId get-device-info message ID
* @param deviceInfo The APNS device info
* @returns Promise
*/
- public async deviceInfo(connectionId: string, deviceInfo: ApnsDeviceInfo) {
+ public async deviceInfo(connectionId: string, threadId: string, deviceInfo: ApnsDeviceInfo) {
const connection = await this.connectionService.getById(this.agentContext, connectionId)
connection.assertReady()
- const message = this.pushNotificationsService.createDeviceInfo(deviceInfo)
+ const message = this.pushNotificationsService.createDeviceInfo({ threadId, deviceInfo })
const outbound = new OutboundMessageContext(message, {
agentContext: this.agentContext,
diff --git a/packages/push-notifications/src/apns/PushNotificationsApnsModule.ts b/packages/push-notifications/src/apns/PushNotificationsApnsModule.ts
index c3c1aa8c..a0e27a1a 100644
--- a/packages/push-notifications/src/apns/PushNotificationsApnsModule.ts
+++ b/packages/push-notifications/src/apns/PushNotificationsApnsModule.ts
@@ -1,12 +1,16 @@
-import type { DependencyManager, Module } from '@aries-framework/core'
+import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core'
+
+import { Protocol } from '@aries-framework/core'
import { PushNotificationsApnsApi } from './PushNotificationsApnsApi'
import { PushNotificationsApnsService } from './PushNotificationsApnsService'
import {
PushNotificationsApnsDeviceInfoHandler,
PushNotificationsApnsGetDeviceInfoHandler,
+ PushNotificationsApnsProblemReportHandler,
PushNotificationsApnsSetDeviceInfoHandler,
} from './handlers'
+import { PushNotificationsApnsRole } from './models'
/**
* Module that exposes push notification get and set functionality
@@ -14,13 +18,21 @@ import {
export class PushNotificationsApnsModule implements Module {
public readonly api = PushNotificationsApnsApi
- public register(dependencyManager: DependencyManager): void {
+ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry): void {
dependencyManager.registerContextScoped(PushNotificationsApnsApi)
+ featureRegistry.register(
+ new Protocol({
+ id: 'https://didcomm.org/push-notifications-apns/1.0',
+ roles: [PushNotificationsApnsRole.Sender, PushNotificationsApnsRole.Receiver],
+ })
+ )
+
dependencyManager.registerMessageHandlers([
new PushNotificationsApnsDeviceInfoHandler(),
new PushNotificationsApnsGetDeviceInfoHandler(),
new PushNotificationsApnsSetDeviceInfoHandler(),
+ new PushNotificationsApnsProblemReportHandler(),
])
dependencyManager.registerSingleton(PushNotificationsApnsService)
diff --git a/packages/push-notifications/src/apns/PushNotificationsApnsService.ts b/packages/push-notifications/src/apns/PushNotificationsApnsService.ts
index 45bf52b7..52730cd3 100644
--- a/packages/push-notifications/src/apns/PushNotificationsApnsService.ts
+++ b/packages/push-notifications/src/apns/PushNotificationsApnsService.ts
@@ -18,7 +18,8 @@ export class PushNotificationsApnsService {
return new PushNotificationsApnsGetDeviceInfoMessage({})
}
- public createDeviceInfo(deviceInfo: ApnsDeviceInfo) {
- return new PushNotificationsApnsDeviceInfoMessage(deviceInfo)
+ public createDeviceInfo(options: { threadId: string; deviceInfo: ApnsDeviceInfo }) {
+ const { threadId, deviceInfo } = options
+ return new PushNotificationsApnsDeviceInfoMessage({ threadId, deviceToken: deviceInfo.deviceToken })
}
}
diff --git a/packages/push-notifications/src/apns/errors/PushNotificationsApnsProblemReportError.ts b/packages/push-notifications/src/apns/errors/PushNotificationsApnsProblemReportError.ts
new file mode 100644
index 00000000..2c7ea1d3
--- /dev/null
+++ b/packages/push-notifications/src/apns/errors/PushNotificationsApnsProblemReportError.ts
@@ -0,0 +1,30 @@
+import type { PushNotificationsApnsProblemReportReason } from './PushNotificationsApnsProblemReportReason'
+import type { ProblemReportErrorOptions } from '@aries-framework/core'
+
+import { ProblemReportError } from '@aries-framework/core'
+
+import { PushNotificationsApnsProblemReportMessage } from '../messages'
+
+/**
+ * @internal
+ */
+interface PushNotificationsApnsProblemReportErrorOptions extends ProblemReportErrorOptions {
+ problemCode: PushNotificationsApnsProblemReportReason
+}
+
+/**
+ * @internal
+ */
+export class PushNotificationsApnsProblemReportError extends ProblemReportError {
+ public problemReport: PushNotificationsApnsProblemReportMessage
+
+ public constructor(public message: string, { problemCode }: PushNotificationsApnsProblemReportErrorOptions) {
+ super(message, { problemCode })
+ this.problemReport = new PushNotificationsApnsProblemReportMessage({
+ description: {
+ en: message,
+ code: problemCode,
+ },
+ })
+ }
+}
diff --git a/packages/push-notifications/src/apns/errors/PushNotificationsApnsProblemReportReason.ts b/packages/push-notifications/src/apns/errors/PushNotificationsApnsProblemReportReason.ts
new file mode 100644
index 00000000..4b163d2e
--- /dev/null
+++ b/packages/push-notifications/src/apns/errors/PushNotificationsApnsProblemReportReason.ts
@@ -0,0 +1,11 @@
+/**
+ * Push Notification APNS errors discussed in RFC 0699.
+ *
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#set-device-info
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#device-info
+ * @internal
+ */
+export enum PushNotificationsApnsProblemReportReason {
+ MissingValue = 'missing-value',
+ NotRegistered = 'not-registered-for-push-notifications',
+}
diff --git a/packages/push-notifications/src/apns/errors/index.ts b/packages/push-notifications/src/apns/errors/index.ts
new file mode 100644
index 00000000..b54dc9d5
--- /dev/null
+++ b/packages/push-notifications/src/apns/errors/index.ts
@@ -0,0 +1,2 @@
+export * from './PushNotificationsApnsProblemReportReason'
+export * from './PushNotificationsApnsProblemReportError'
diff --git a/packages/push-notifications/src/apns/handlers/PushNotificationsApnsProblemReportHandler.ts b/packages/push-notifications/src/apns/handlers/PushNotificationsApnsProblemReportHandler.ts
new file mode 100644
index 00000000..78763c36
--- /dev/null
+++ b/packages/push-notifications/src/apns/handlers/PushNotificationsApnsProblemReportHandler.ts
@@ -0,0 +1,18 @@
+import type { MessageHandler, MessageHandlerInboundMessage } from '@aries-framework/core'
+
+import { PushNotificationsApnsProblemReportMessage } from '../messages'
+
+/**
+ * Handler for incoming push notification problem report messages
+ */
+export class PushNotificationsApnsProblemReportHandler implements MessageHandler {
+ public supportedMessages = [PushNotificationsApnsProblemReportMessage]
+
+ /**
+ /* We don't really need to do anything with this at the moment
+ /* The result can be hooked into through the generic message processed event
+ */
+ public async handle(inboundMessage: MessageHandlerInboundMessage) {
+ inboundMessage.assertReadyConnection()
+ }
+}
diff --git a/packages/push-notifications/src/apns/handlers/index.ts b/packages/push-notifications/src/apns/handlers/index.ts
index c2996201..20d9c0e7 100644
--- a/packages/push-notifications/src/apns/handlers/index.ts
+++ b/packages/push-notifications/src/apns/handlers/index.ts
@@ -1,3 +1,4 @@
export { PushNotificationsApnsGetDeviceInfoHandler } from './PushNotificationsApnsGetDeviceInfoHandler'
export { PushNotificationsApnsSetDeviceInfoHandler } from './PushNotificationsApnsSetDeviceInfoHandler'
export { PushNotificationsApnsDeviceInfoHandler } from './PushNotificationsApnsDeviceInfoHandler'
+export { PushNotificationsApnsProblemReportHandler } from './PushNotificationsApnsProblemReportHandler'
diff --git a/packages/push-notifications/src/apns/messages/PushNotificationsApnsDeviceInfoMessage.ts b/packages/push-notifications/src/apns/messages/PushNotificationsApnsDeviceInfoMessage.ts
index 1b856636..aa1d2f0e 100644
--- a/packages/push-notifications/src/apns/messages/PushNotificationsApnsDeviceInfoMessage.ts
+++ b/packages/push-notifications/src/apns/messages/PushNotificationsApnsDeviceInfoMessage.ts
@@ -2,17 +2,18 @@ import type { ApnsDeviceInfo } from '../models'
import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'
import { Expose } from 'class-transformer'
-import { IsString } from 'class-validator'
+import { IsString, ValidateIf } from 'class-validator'
interface PushNotificationsApnsDeviceInfoOptions extends ApnsDeviceInfo {
id?: string
+ threadId: string
}
/**
* Message to send the apns device information from another agent for push notifications
* This is used as a response for the `get-device-info` message
*
- * @todo ADD RFC
+ * @todo @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#device-info
*/
export class PushNotificationsApnsDeviceInfoMessage extends AgentMessage {
public constructor(options: PushNotificationsApnsDeviceInfoOptions) {
@@ -20,6 +21,7 @@ export class PushNotificationsApnsDeviceInfoMessage extends AgentMessage {
if (options) {
this.id = options.id ?? this.generateId()
+ this.setThread({ threadId: options.threadId })
this.deviceToken = options.deviceToken
}
}
@@ -30,5 +32,6 @@ export class PushNotificationsApnsDeviceInfoMessage extends AgentMessage {
@Expose({ name: 'device_token' })
@IsString()
- public deviceToken!: string
+ @ValidateIf((object, value) => value !== null)
+ public deviceToken!: string | null
}
diff --git a/packages/push-notifications/src/apns/messages/PushNotificationsApnsGetDeviceInfoMessage.ts b/packages/push-notifications/src/apns/messages/PushNotificationsApnsGetDeviceInfoMessage.ts
index 35b2f8db..d4bfb64d 100644
--- a/packages/push-notifications/src/apns/messages/PushNotificationsApnsGetDeviceInfoMessage.ts
+++ b/packages/push-notifications/src/apns/messages/PushNotificationsApnsGetDeviceInfoMessage.ts
@@ -7,7 +7,7 @@ interface PushNotificationsApnsGetDeviceInfoOptions {
/**
* Message to get the apns device information from another agent for push notifications
*
- * @todo ADD RFC
+ * @todo @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#get-device-info
*/
export class PushNotificationsApnsGetDeviceInfoMessage extends AgentMessage {
public constructor(options: PushNotificationsApnsGetDeviceInfoOptions) {
diff --git a/packages/push-notifications/src/apns/messages/PushNotificationsApnsProblemReportMessage.ts b/packages/push-notifications/src/apns/messages/PushNotificationsApnsProblemReportMessage.ts
new file mode 100644
index 00000000..17a81524
--- /dev/null
+++ b/packages/push-notifications/src/apns/messages/PushNotificationsApnsProblemReportMessage.ts
@@ -0,0 +1,23 @@
+import type { ProblemReportMessageOptions } from '@aries-framework/core'
+
+import { IsValidMessageType, parseMessageType, ProblemReportMessage } from '@aries-framework/core'
+
+export type PushNotificationsApnsProblemReportMessageOptions = ProblemReportMessageOptions
+
+/**
+ * @see https://github.com/hyperledger/aries-rfcs/blob/main/features/0035-report-problem/README.md
+ * @internal
+ */
+export class PushNotificationsApnsProblemReportMessage extends ProblemReportMessage {
+ /**
+ * Create new ConnectionProblemReportMessage instance.
+ * @param options
+ */
+ public constructor(options: PushNotificationsApnsProblemReportMessageOptions) {
+ super(options)
+ }
+
+ @IsValidMessageType(PushNotificationsApnsProblemReportMessage.type)
+ public readonly type = PushNotificationsApnsProblemReportMessage.type.messageTypeUri
+ public static readonly type = parseMessageType('https://didcomm.org/push-notifications-apns/1.0/problem-report')
+}
diff --git a/packages/push-notifications/src/apns/messages/PushNotificationsApnsSetDeviceInfoMessage.ts b/packages/push-notifications/src/apns/messages/PushNotificationsApnsSetDeviceInfoMessage.ts
index 528c0f8c..dd83c74e 100644
--- a/packages/push-notifications/src/apns/messages/PushNotificationsApnsSetDeviceInfoMessage.ts
+++ b/packages/push-notifications/src/apns/messages/PushNotificationsApnsSetDeviceInfoMessage.ts
@@ -2,7 +2,7 @@ import type { ApnsDeviceInfo } from '../models'
import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'
import { Expose } from 'class-transformer'
-import { IsString } from 'class-validator'
+import { IsString, ValidateIf } from 'class-validator'
interface PushNotificationsApnsSetDeviceInfoOptions extends ApnsDeviceInfo {
id?: string
@@ -11,7 +11,7 @@ interface PushNotificationsApnsSetDeviceInfoOptions extends ApnsDeviceInfo {
/**
* Message to set the apns device information at another agent for push notifications
*
- * @todo ADD RFC
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#set-device-info
*/
export class PushNotificationsApnsSetDeviceInfoMessage extends AgentMessage {
public constructor(options: PushNotificationsApnsSetDeviceInfoOptions) {
@@ -25,7 +25,8 @@ export class PushNotificationsApnsSetDeviceInfoMessage extends AgentMessage {
@Expose({ name: 'device_token' })
@IsString()
- public deviceToken!: string
+ @ValidateIf((object, value) => value !== null)
+ public deviceToken!: string | null
@IsValidMessageType(PushNotificationsApnsSetDeviceInfoMessage.type)
public readonly type = PushNotificationsApnsSetDeviceInfoMessage.type.messageTypeUri
diff --git a/packages/push-notifications/src/apns/messages/index.ts b/packages/push-notifications/src/apns/messages/index.ts
index 39dd8163..6a92ba33 100644
--- a/packages/push-notifications/src/apns/messages/index.ts
+++ b/packages/push-notifications/src/apns/messages/index.ts
@@ -1,3 +1,4 @@
export { PushNotificationsApnsGetDeviceInfoMessage } from './PushNotificationsApnsGetDeviceInfoMessage'
export { PushNotificationsApnsSetDeviceInfoMessage } from './PushNotificationsApnsSetDeviceInfoMessage'
export { PushNotificationsApnsDeviceInfoMessage } from './PushNotificationsApnsDeviceInfoMessage'
+export { PushNotificationsApnsProblemReportMessage } from './PushNotificationsApnsProblemReportMessage'
diff --git a/packages/push-notifications/src/apns/models/ApnsDeviceInfo.ts b/packages/push-notifications/src/apns/models/ApnsDeviceInfo.ts
index 6e7013c1..e8db2a7d 100644
--- a/packages/push-notifications/src/apns/models/ApnsDeviceInfo.ts
+++ b/packages/push-notifications/src/apns/models/ApnsDeviceInfo.ts
@@ -1,3 +1,3 @@
export type ApnsDeviceInfo = {
- deviceToken: string
+ deviceToken: string | null
}
diff --git a/packages/push-notifications/src/apns/models/PushNotificationsApnsRole.ts b/packages/push-notifications/src/apns/models/PushNotificationsApnsRole.ts
new file mode 100644
index 00000000..5900541f
--- /dev/null
+++ b/packages/push-notifications/src/apns/models/PushNotificationsApnsRole.ts
@@ -0,0 +1,10 @@
+/**
+ * Push Notification FCM roles based on the flow defined in RFC 0699.
+ *
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#roles
+ * @public
+ */
+export enum PushNotificationsApnsRole {
+ Sender = 'notification-sender',
+ Receiver = 'notification-receiver',
+}
diff --git a/packages/push-notifications/src/apns/models/index.ts b/packages/push-notifications/src/apns/models/index.ts
index c8e35f78..20a09fbc 100644
--- a/packages/push-notifications/src/apns/models/index.ts
+++ b/packages/push-notifications/src/apns/models/index.ts
@@ -1 +1,2 @@
export * from './ApnsDeviceInfo'
+export * from './PushNotificationsApnsRole'
diff --git a/packages/push-notifications/src/fcm/PushNotificationsFcmApi.ts b/packages/push-notifications/src/fcm/PushNotificationsFcmApi.ts
index 08f51a63..3c1aceed 100644
--- a/packages/push-notifications/src/fcm/PushNotificationsFcmApi.ts
+++ b/packages/push-notifications/src/fcm/PushNotificationsFcmApi.ts
@@ -54,14 +54,15 @@ export class PushNotificationsFcmApi {
* Response for `push-notifications-fcm/get-device-info`
*
* @param connectionId The connection ID string
+ * @param threadId get-device-info message ID
* @param deviceInfo The FCM device info
* @returns Promise
*/
- public async deviceInfo(connectionId: string, deviceInfo: FcmDeviceInfo) {
+ public async deviceInfo(connectionId: string, threadId: string, deviceInfo: FcmDeviceInfo) {
const connection = await this.connectionService.getById(this.agentContext, connectionId)
connection.assertReady()
- const message = this.pushNotificationsService.createDeviceInfo(deviceInfo)
+ const message = this.pushNotificationsService.createDeviceInfo({ threadId, deviceInfo })
const outbound = new OutboundMessageContext(message, {
agentContext: this.agentContext,
diff --git a/packages/push-notifications/src/fcm/PushNotificationsFcmModule.ts b/packages/push-notifications/src/fcm/PushNotificationsFcmModule.ts
index c85de8ce..1c3f563f 100644
--- a/packages/push-notifications/src/fcm/PushNotificationsFcmModule.ts
+++ b/packages/push-notifications/src/fcm/PushNotificationsFcmModule.ts
@@ -1,12 +1,16 @@
-import type { DependencyManager, Module } from '@aries-framework/core'
+import type { DependencyManager, FeatureRegistry, Module } from '@aries-framework/core'
+
+import { Protocol } from '@aries-framework/core'
import { PushNotificationsFcmApi } from './PushNotificationsFcmApi'
import { PushNotificationsFcmService } from './PushNotificationsFcmService'
import {
PushNotificationsFcmDeviceInfoHandler,
PushNotificationsFcmGetDeviceInfoHandler,
+ PushNotificationsFcmProblemReportHandler,
PushNotificationsFcmSetDeviceInfoHandler,
} from './handlers'
+import { PushNotificationsFcmRole } from './models'
/**
* Module that exposes push notification get and set functionality
@@ -14,15 +18,23 @@ import {
export class PushNotificationsFcmModule implements Module {
public readonly api = PushNotificationsFcmApi
- public register(dependencyManager: DependencyManager): void {
+ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry): void {
dependencyManager.registerContextScoped(PushNotificationsFcmApi)
dependencyManager.registerSingleton(PushNotificationsFcmService)
+ featureRegistry.register(
+ new Protocol({
+ id: 'https://didcomm.org/push-notifications-fcm/1.0',
+ roles: [PushNotificationsFcmRole.Sender, PushNotificationsFcmRole.Receiver],
+ })
+ )
+
dependencyManager.registerMessageHandlers([
new PushNotificationsFcmDeviceInfoHandler(),
new PushNotificationsFcmGetDeviceInfoHandler(),
new PushNotificationsFcmSetDeviceInfoHandler(),
+ new PushNotificationsFcmProblemReportHandler(),
])
}
}
diff --git a/packages/push-notifications/src/fcm/PushNotificationsFcmService.ts b/packages/push-notifications/src/fcm/PushNotificationsFcmService.ts
index 88ff0165..677d9d84 100644
--- a/packages/push-notifications/src/fcm/PushNotificationsFcmService.ts
+++ b/packages/push-notifications/src/fcm/PushNotificationsFcmService.ts
@@ -1,7 +1,10 @@
import type { FcmDeviceInfo } from './models/FcmDeviceInfo'
+import type { InboundMessageContext } from '@aries-framework/core'
+import { AriesFrameworkError } from '@aries-framework/core'
import { Lifecycle, scoped } from 'tsyringe'
+import { PushNotificationsFcmProblemReportError, PushNotificationsFcmProblemReportReason } from './errors'
import {
PushNotificationsFcmSetDeviceInfoMessage,
PushNotificationsFcmGetDeviceInfoMessage,
@@ -11,6 +14,12 @@ import {
@scoped(Lifecycle.ContainerScoped)
export class PushNotificationsFcmService {
public createSetDeviceInfo(deviceInfo: FcmDeviceInfo) {
+ if (
+ (deviceInfo.deviceToken === null && deviceInfo.devicePlatform !== null) ||
+ (deviceInfo.deviceToken !== null && deviceInfo.devicePlatform === null)
+ )
+ throw new AriesFrameworkError('Both or none of deviceToken and devicePlatform must be null')
+
return new PushNotificationsFcmSetDeviceInfoMessage(deviceInfo)
}
@@ -18,7 +27,29 @@ export class PushNotificationsFcmService {
return new PushNotificationsFcmGetDeviceInfoMessage({})
}
- public createDeviceInfo(deviceInfo: FcmDeviceInfo) {
- return new PushNotificationsFcmDeviceInfoMessage(deviceInfo)
+ public createDeviceInfo(options: { threadId: string; deviceInfo: FcmDeviceInfo }) {
+ const { threadId, deviceInfo } = options
+ if (
+ (deviceInfo.deviceToken === null && deviceInfo.devicePlatform !== null) ||
+ (deviceInfo.deviceToken !== null && deviceInfo.devicePlatform === null)
+ )
+ throw new AriesFrameworkError('Both or none of deviceToken and devicePlatform must be null')
+
+ return new PushNotificationsFcmDeviceInfoMessage({
+ threadId,
+ deviceToken: deviceInfo.deviceToken,
+ devicePlatform: deviceInfo.devicePlatform,
+ })
+ }
+
+ public processSetDeviceInfo(messageContext: InboundMessageContext) {
+ const { message } = messageContext
+ if (
+ (message.deviceToken === null && message.devicePlatform !== null) ||
+ (message.deviceToken !== null && message.devicePlatform === null)
+ )
+ throw new PushNotificationsFcmProblemReportError('Both or none of deviceToken and devicePlatform must be null', {
+ problemCode: PushNotificationsFcmProblemReportReason.MissingValue,
+ })
}
}
diff --git a/packages/push-notifications/src/fcm/errors/PushNotificationsFcmProblemReportError.ts b/packages/push-notifications/src/fcm/errors/PushNotificationsFcmProblemReportError.ts
new file mode 100644
index 00000000..c1e973a0
--- /dev/null
+++ b/packages/push-notifications/src/fcm/errors/PushNotificationsFcmProblemReportError.ts
@@ -0,0 +1,30 @@
+import type { PushNotificationsFcmProblemReportReason } from './PushNotificationsFcmProblemReportReason'
+import type { ProblemReportErrorOptions } from '@aries-framework/core'
+
+import { ProblemReportError } from '@aries-framework/core'
+
+import { PushNotificationsFcmProblemReportMessage } from '../messages'
+
+/**
+ * @internal
+ */
+interface PushNotificationsFcmProblemReportErrorOptions extends ProblemReportErrorOptions {
+ problemCode: PushNotificationsFcmProblemReportReason
+}
+
+/**
+ * @internal
+ */
+export class PushNotificationsFcmProblemReportError extends ProblemReportError {
+ public problemReport: PushNotificationsFcmProblemReportMessage
+
+ public constructor(public message: string, { problemCode }: PushNotificationsFcmProblemReportErrorOptions) {
+ super(message, { problemCode })
+ this.problemReport = new PushNotificationsFcmProblemReportMessage({
+ description: {
+ en: message,
+ code: problemCode,
+ },
+ })
+ }
+}
diff --git a/packages/push-notifications/src/fcm/errors/PushNotificationsFcmProblemReportReason.ts b/packages/push-notifications/src/fcm/errors/PushNotificationsFcmProblemReportReason.ts
new file mode 100644
index 00000000..fd6f3446
--- /dev/null
+++ b/packages/push-notifications/src/fcm/errors/PushNotificationsFcmProblemReportReason.ts
@@ -0,0 +1,11 @@
+/**
+ * Push Notification FCM errors discussed in RFC 0734.
+ *
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0734-push-notifications-fcm#set-device-info
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0734-push-notifications-fcm#device-info
+ * @internal
+ */
+export enum PushNotificationsFcmProblemReportReason {
+ MissingValue = 'missing-value',
+ NotRegistered = 'not-registered-for-push-notifications',
+}
diff --git a/packages/push-notifications/src/fcm/errors/index.ts b/packages/push-notifications/src/fcm/errors/index.ts
new file mode 100644
index 00000000..a1155d8a
--- /dev/null
+++ b/packages/push-notifications/src/fcm/errors/index.ts
@@ -0,0 +1,2 @@
+export * from './PushNotificationsFcmProblemReportReason'
+export * from './PushNotificationsFcmProblemReportError'
diff --git a/packages/push-notifications/src/fcm/handlers/PushNotificationsFcmProblemReportHandler.ts b/packages/push-notifications/src/fcm/handlers/PushNotificationsFcmProblemReportHandler.ts
new file mode 100644
index 00000000..c14c622d
--- /dev/null
+++ b/packages/push-notifications/src/fcm/handlers/PushNotificationsFcmProblemReportHandler.ts
@@ -0,0 +1,18 @@
+import type { MessageHandler, MessageHandlerInboundMessage } from '@aries-framework/core'
+
+import { PushNotificationsFcmProblemReportMessage } from '../messages'
+
+/**
+ * Handler for incoming push notification problem report messages
+ */
+export class PushNotificationsFcmProblemReportHandler implements MessageHandler {
+ public supportedMessages = [PushNotificationsFcmProblemReportMessage]
+
+ /**
+ /* We don't really need to do anything with this at the moment
+ /* The result can be hooked into through the generic message processed event
+ */
+ public async handle(inboundMessage: MessageHandlerInboundMessage) {
+ inboundMessage.assertReadyConnection()
+ }
+}
diff --git a/packages/push-notifications/src/fcm/handlers/PushNotificationsFcmSetDeviceInfoHandler.ts b/packages/push-notifications/src/fcm/handlers/PushNotificationsFcmSetDeviceInfoHandler.ts
index e631c98e..d94d20dd 100644
--- a/packages/push-notifications/src/fcm/handlers/PushNotificationsFcmSetDeviceInfoHandler.ts
+++ b/packages/push-notifications/src/fcm/handlers/PushNotificationsFcmSetDeviceInfoHandler.ts
@@ -1,5 +1,6 @@
import type { MessageHandler, MessageHandlerInboundMessage } from '@aries-framework/core'
+import { PushNotificationsFcmService } from '../PushNotificationsFcmService'
import { PushNotificationsFcmSetDeviceInfoMessage } from '../messages'
/**
@@ -9,10 +10,15 @@ export class PushNotificationsFcmSetDeviceInfoHandler implements MessageHandler
public supportedMessages = [PushNotificationsFcmSetDeviceInfoMessage]
/**
- /* We don't really need to do anything with this at the moment
+ /* Only perform checks about message fields
+ /*
/* The result can be hooked into through the generic message processed event
*/
public async handle(inboundMessage: MessageHandlerInboundMessage) {
inboundMessage.assertReadyConnection()
+
+ const pushNotificationsFcmService =
+ inboundMessage.agentContext.dependencyManager.resolve(PushNotificationsFcmService)
+ pushNotificationsFcmService.processSetDeviceInfo(inboundMessage)
}
}
diff --git a/packages/push-notifications/src/fcm/handlers/index.ts b/packages/push-notifications/src/fcm/handlers/index.ts
index cabdaa0d..ea2c5409 100644
--- a/packages/push-notifications/src/fcm/handlers/index.ts
+++ b/packages/push-notifications/src/fcm/handlers/index.ts
@@ -1,3 +1,4 @@
export { PushNotificationsFcmDeviceInfoHandler } from './PushNotificationsFcmDeviceInfoHandler'
export { PushNotificationsFcmGetDeviceInfoHandler } from './PushNotificationsFcmGetDeviceInfoHandler'
export { PushNotificationsFcmSetDeviceInfoHandler } from './PushNotificationsFcmSetDeviceInfoHandler'
+export { PushNotificationsFcmProblemReportHandler } from './PushNotificationsFcmProblemReportHandler'
diff --git a/packages/push-notifications/src/fcm/messages/PushNotificationsFcmDeviceInfoMessage.ts b/packages/push-notifications/src/fcm/messages/PushNotificationsFcmDeviceInfoMessage.ts
index dbad8883..6b333469 100644
--- a/packages/push-notifications/src/fcm/messages/PushNotificationsFcmDeviceInfoMessage.ts
+++ b/packages/push-notifications/src/fcm/messages/PushNotificationsFcmDeviceInfoMessage.ts
@@ -2,17 +2,18 @@ import type { FcmDeviceInfo } from '../models'
import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'
import { Expose } from 'class-transformer'
-import { IsString } from 'class-validator'
+import { IsString, ValidateIf } from 'class-validator'
interface PushNotificationsFcmDeviceInfoOptions extends FcmDeviceInfo {
id?: string
+ threadId: string
}
/**
* Message to send the fcm device information from another agent for push notifications
* This is used as a response for the `get-device-info` message
*
- * @todo ADD RFC
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0734-push-notifications-fcm#device-info
*/
export class PushNotificationsFcmDeviceInfoMessage extends AgentMessage {
public constructor(options: PushNotificationsFcmDeviceInfoOptions) {
@@ -20,13 +21,21 @@ export class PushNotificationsFcmDeviceInfoMessage extends AgentMessage {
if (options) {
this.id = options.id ?? this.generateId()
+ this.setThread({ threadId: options.threadId })
this.deviceToken = options.deviceToken
+ this.devicePlatform = options.devicePlatform
}
}
@Expose({ name: 'device_token' })
@IsString()
- public deviceToken!: string
+ @ValidateIf((object, value) => value !== null)
+ public deviceToken!: string | null
+
+ @Expose({ name: 'device_platform' })
+ @IsString()
+ @ValidateIf((object, value) => value !== null)
+ public devicePlatform!: string | null
@IsValidMessageType(PushNotificationsFcmDeviceInfoMessage.type)
public readonly type = PushNotificationsFcmDeviceInfoMessage.type.messageTypeUri
diff --git a/packages/push-notifications/src/fcm/messages/PushNotificationsFcmGetDeviceInfoMessage.ts b/packages/push-notifications/src/fcm/messages/PushNotificationsFcmGetDeviceInfoMessage.ts
index dc21647e..c20ebca8 100644
--- a/packages/push-notifications/src/fcm/messages/PushNotificationsFcmGetDeviceInfoMessage.ts
+++ b/packages/push-notifications/src/fcm/messages/PushNotificationsFcmGetDeviceInfoMessage.ts
@@ -7,7 +7,7 @@ interface PushNotificationsFcmGetDeviceInfoOptions {
/**
* Message to get fcm the device information from another agent for push notifications
*
- * @todo ADD RFC
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0734-push-notifications-fcm#get-device-info
*/
export class PushNotificationsFcmGetDeviceInfoMessage extends AgentMessage {
public constructor(options: PushNotificationsFcmGetDeviceInfoOptions) {
diff --git a/packages/push-notifications/src/fcm/messages/PushNotificationsFcmProblemReportMessage.ts b/packages/push-notifications/src/fcm/messages/PushNotificationsFcmProblemReportMessage.ts
new file mode 100644
index 00000000..df86cb86
--- /dev/null
+++ b/packages/push-notifications/src/fcm/messages/PushNotificationsFcmProblemReportMessage.ts
@@ -0,0 +1,23 @@
+import type { ProblemReportMessageOptions } from '@aries-framework/core'
+
+import { IsValidMessageType, parseMessageType, ProblemReportMessage } from '@aries-framework/core'
+
+export type PushNotificationsFcmProblemReportMessageOptions = ProblemReportMessageOptions
+
+/**
+ * @see https://github.com/hyperledger/aries-rfcs/blob/main/features/0035-report-problem/README.md
+ * @internal
+ */
+export class PushNotificationsFcmProblemReportMessage extends ProblemReportMessage {
+ /**
+ * Create new ConnectionProblemReportMessage instance.
+ * @param options
+ */
+ public constructor(options: PushNotificationsFcmProblemReportMessageOptions) {
+ super(options)
+ }
+
+ @IsValidMessageType(PushNotificationsFcmProblemReportMessage.type)
+ public readonly type = PushNotificationsFcmProblemReportMessage.type.messageTypeUri
+ public static readonly type = parseMessageType('https://didcomm.org/push-notifications-fcm/1.0/problem-report')
+}
diff --git a/packages/push-notifications/src/fcm/messages/PushNotificationsFcmSetDeviceInfoMessage.ts b/packages/push-notifications/src/fcm/messages/PushNotificationsFcmSetDeviceInfoMessage.ts
index 2b155ccf..8115b213 100644
--- a/packages/push-notifications/src/fcm/messages/PushNotificationsFcmSetDeviceInfoMessage.ts
+++ b/packages/push-notifications/src/fcm/messages/PushNotificationsFcmSetDeviceInfoMessage.ts
@@ -2,7 +2,7 @@ import type { FcmDeviceInfo } from '../models'
import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core'
import { Expose } from 'class-transformer'
-import { IsString } from 'class-validator'
+import { IsString, ValidateIf } from 'class-validator'
interface PushNotificationsFcmSetDeviceInfoOptions extends FcmDeviceInfo {
id?: string
@@ -11,7 +11,7 @@ interface PushNotificationsFcmSetDeviceInfoOptions extends FcmDeviceInfo {
/**
* Message to set the fcm device information at another agent for push notifications
*
- * @todo ADD RFC
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0734-push-notifications-fcm#set-device-info
*/
export class PushNotificationsFcmSetDeviceInfoMessage extends AgentMessage {
public constructor(options: PushNotificationsFcmSetDeviceInfoOptions) {
@@ -20,12 +20,19 @@ export class PushNotificationsFcmSetDeviceInfoMessage extends AgentMessage {
if (options) {
this.id = options.id ?? this.generateId()
this.deviceToken = options.deviceToken
+ this.devicePlatform = options.devicePlatform
}
}
@Expose({ name: 'device_token' })
@IsString()
- public deviceToken!: string
+ @ValidateIf((object, value) => value !== null)
+ public deviceToken!: string | null
+
+ @Expose({ name: 'device_platform' })
+ @IsString()
+ @ValidateIf((object, value) => value !== null)
+ public devicePlatform!: string | null
@IsValidMessageType(PushNotificationsFcmSetDeviceInfoMessage.type)
public readonly type = PushNotificationsFcmSetDeviceInfoMessage.type.messageTypeUri
diff --git a/packages/push-notifications/src/fcm/messages/index.ts b/packages/push-notifications/src/fcm/messages/index.ts
index f064c187..59f3aee1 100644
--- a/packages/push-notifications/src/fcm/messages/index.ts
+++ b/packages/push-notifications/src/fcm/messages/index.ts
@@ -1,3 +1,4 @@
export { PushNotificationsFcmDeviceInfoMessage } from './PushNotificationsFcmDeviceInfoMessage'
export { PushNotificationsFcmGetDeviceInfoMessage } from './PushNotificationsFcmGetDeviceInfoMessage'
export { PushNotificationsFcmSetDeviceInfoMessage } from './PushNotificationsFcmSetDeviceInfoMessage'
+export { PushNotificationsFcmProblemReportMessage } from './PushNotificationsFcmProblemReportMessage'
diff --git a/packages/push-notifications/src/fcm/models/FcmDeviceInfo.ts b/packages/push-notifications/src/fcm/models/FcmDeviceInfo.ts
index f0aad43f..644c230d 100644
--- a/packages/push-notifications/src/fcm/models/FcmDeviceInfo.ts
+++ b/packages/push-notifications/src/fcm/models/FcmDeviceInfo.ts
@@ -1,3 +1,4 @@
export type FcmDeviceInfo = {
- deviceToken: string
+ deviceToken: string | null
+ devicePlatform: string | null
}
diff --git a/packages/push-notifications/src/fcm/models/PushNotificationsFcmRole.ts b/packages/push-notifications/src/fcm/models/PushNotificationsFcmRole.ts
new file mode 100644
index 00000000..e94cbc7d
--- /dev/null
+++ b/packages/push-notifications/src/fcm/models/PushNotificationsFcmRole.ts
@@ -0,0 +1,10 @@
+/**
+ * Push Notification FCM roles based on the flow defined in RFC 0734.
+ *
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0734-push-notifications-fcm#roles
+ * @public
+ */
+export enum PushNotificationsFcmRole {
+ Sender = 'notification-sender',
+ Receiver = 'notification-receiver',
+}
diff --git a/packages/push-notifications/src/fcm/models/index.ts b/packages/push-notifications/src/fcm/models/index.ts
index 4cd264aa..a30d50c8 100644
--- a/packages/push-notifications/src/fcm/models/index.ts
+++ b/packages/push-notifications/src/fcm/models/index.ts
@@ -1 +1,2 @@
export * from './FcmDeviceInfo'
+export * from './PushNotificationsFcmRole'
diff --git a/packages/push-notifications/tests/pushNotificationsApnsService.test.ts b/packages/push-notifications/tests/pushNotificationsApnsService.test.ts
index 678dda61..d3fecce9 100644
--- a/packages/push-notifications/tests/pushNotificationsApnsService.test.ts
+++ b/packages/push-notifications/tests/pushNotificationsApnsService.test.ts
@@ -25,16 +25,22 @@ describe('Push Notifications apns', () => {
describe('Create apns set push notification message', () => {
test('Should create a valid https://didcomm.org/push-notifications-apns/1.0/device-info message ', async () => {
const message = pushNotificationsApnsService.createDeviceInfo({
- deviceToken: '1234-1234-1234-1234',
+ threadId: '5678-5678-5678-5678',
+ deviceInfo: {
+ deviceToken: '1234-1234-1234-1234',
+ },
})
const jsonMessage = JsonTransformer.toJSON(message)
- expect(jsonMessage).toEqual({
- '@id': expect.any(String),
- '@type': 'https://didcomm.org/push-notifications-apns/1.0/device-info',
- device_token: '1234-1234-1234-1234',
- })
+ expect(jsonMessage).toEqual(
+ expect.objectContaining({
+ '@id': expect.any(String),
+ '@type': 'https://didcomm.org/push-notifications-apns/1.0/device-info',
+ device_token: '1234-1234-1234-1234',
+ '~thread': expect.objectContaining({ thid: '5678-5678-5678-5678' }),
+ })
+ )
})
})
describe('Create apns set push notification message', () => {
diff --git a/packages/push-notifications/tests/pushNotificationsFcmService.test.ts b/packages/push-notifications/tests/pushNotificationsFcmService.test.ts
index 43e8e427..a343c1c7 100644
--- a/packages/push-notifications/tests/pushNotificationsFcmService.test.ts
+++ b/packages/push-notifications/tests/pushNotificationsFcmService.test.ts
@@ -1,8 +1,9 @@
-import type { Agent } from '@aries-framework/core'
+import type { Agent, AgentMessage, ConnectionRecord } from '@aries-framework/core'
-import { JsonTransformer } from '@aries-framework/core'
+import { AgentContext, DependencyManager, JsonTransformer } from '@aries-framework/core'
import { PushNotificationsFcmService } from '../src/fcm/PushNotificationsFcmService'
+import { PushNotificationsFcmProblemReportError } from '../src/fcm/errors'
import { setupAgentFcm } from './utils/agent'
@@ -23,10 +24,11 @@ describe('Push Notifications Fcm ', () => {
await agent.wallet.delete()
})
- describe('Create fcm set push notification message', () => {
- test('Should create a valid https://didcomm.org/push-notifications-fcm/1.0/set-device-info message ', async () => {
+ describe('Create fcm set-device-info message', () => {
+ test('Should create a valid message with both token and platform', async () => {
const message = pushNotificationsService.createSetDeviceInfo({
deviceToken: '1234-1234-1234-1234',
+ devicePlatform: 'android',
})
const jsonMessage = JsonTransformer.toJSON(message)
@@ -35,12 +37,45 @@ describe('Push Notifications Fcm ', () => {
'@id': expect.any(String),
'@type': 'https://didcomm.org/push-notifications-fcm/1.0/set-device-info',
device_token: '1234-1234-1234-1234',
+ device_platform: 'android',
})
})
+
+ test('Should create a valid message without token and platform ', async () => {
+ const message = pushNotificationsService.createSetDeviceInfo({
+ deviceToken: null,
+ devicePlatform: null,
+ })
+
+ const jsonMessage = JsonTransformer.toJSON(message)
+
+ expect(jsonMessage).toEqual({
+ '@id': expect.any(String),
+ '@type': 'https://didcomm.org/push-notifications-fcm/1.0/set-device-info',
+ device_token: null,
+ device_platform: null,
+ })
+ })
+
+ test('Should throw error if either token or platform are missing', async () => {
+ expect(() =>
+ pushNotificationsService.createSetDeviceInfo({
+ deviceToken: 'something',
+ devicePlatform: null,
+ })
+ ).toThrow('Both or none of deviceToken and devicePlatform must be null')
+
+ expect(() =>
+ pushNotificationsService.createSetDeviceInfo({
+ deviceToken: null,
+ devicePlatform: 'something',
+ })
+ ).toThrow('Both or none of deviceToken and devicePlatform must be null')
+ })
})
- describe('Create fcm get device info message', () => {
- test('Should create a valid https://didcomm.org/push-notifications-fcm/1.0/get-device-info message ', async () => {
+ describe('Create fcm get-device-info message', () => {
+ test('Should create a valid message ', async () => {
const message = pushNotificationsService.createGetDeviceInfo()
const jsonMessage = JsonTransformer.toJSON(message)
@@ -52,19 +87,114 @@ describe('Push Notifications Fcm ', () => {
})
})
- describe('Create fcm device info message', () => {
- test('Should create a valid https://didcomm.org/push-notifications-fcm/1.0/device-info message ', async () => {
+ describe('Create fcm device-info message', () => {
+ test('Should create a valid message with both token and platform', async () => {
const message = pushNotificationsService.createDeviceInfo({
- deviceToken: '1234-1234-1234-1234',
+ threadId: '5678-5678-5678-5678',
+ deviceInfo: {
+ deviceToken: '1234-1234-1234-1234',
+ devicePlatform: 'android',
+ },
})
const jsonMessage = JsonTransformer.toJSON(message)
- expect(jsonMessage).toEqual({
- '@id': expect.any(String),
- '@type': 'https://didcomm.org/push-notifications-fcm/1.0/device-info',
- device_token: '1234-1234-1234-1234',
+ expect(jsonMessage).toEqual(
+ expect.objectContaining({
+ '@id': expect.any(String),
+ '@type': 'https://didcomm.org/push-notifications-fcm/1.0/device-info',
+ device_token: '1234-1234-1234-1234',
+ device_platform: 'android',
+ '~thread': expect.objectContaining({ thid: '5678-5678-5678-5678' }),
+ })
+ )
+ })
+
+ test('Should create a valid message without token and platform ', async () => {
+ const message = pushNotificationsService.createDeviceInfo({
+ threadId: '5678-5678-5678-5678',
+ deviceInfo: {
+ deviceToken: null,
+ devicePlatform: null,
+ },
})
+
+ const jsonMessage = JsonTransformer.toJSON(message)
+
+ expect(jsonMessage).toEqual(
+ expect.objectContaining({
+ '@id': expect.any(String),
+ '@type': 'https://didcomm.org/push-notifications-fcm/1.0/device-info',
+ device_token: null,
+ device_platform: null,
+ '~thread': expect.objectContaining({ thid: '5678-5678-5678-5678' }),
+ })
+ )
+ })
+
+ test('Should throw error if either token or platform are missing', async () => {
+ expect(() =>
+ pushNotificationsService.createDeviceInfo({
+ threadId: '5678-5678-5678-5678',
+ deviceInfo: {
+ deviceToken: 'something',
+ devicePlatform: null,
+ },
+ })
+ ).toThrow('Both or none of deviceToken and devicePlatform must be null')
+
+ expect(() =>
+ pushNotificationsService.createDeviceInfo({
+ threadId: '5678-5678-5678-5678',
+ deviceInfo: {
+ deviceToken: null,
+ devicePlatform: 'something',
+ },
+ })
+ ).toThrow('Both or none of deviceToken and devicePlatform must be null')
+ })
+ })
+
+ describe('Process fcm set-device-info message', () => {
+ test('Should throw if one of token and platform are missing', async () => {
+ const message = pushNotificationsService.createSetDeviceInfo({
+ deviceToken: '1234-1234-1234-1234',
+ devicePlatform: 'android',
+ })
+
+ message.devicePlatform = null
+ expect(() => pushNotificationsService.processSetDeviceInfo(createInboundMessageContext(message))).toThrow(
+ PushNotificationsFcmProblemReportError
+ )
+
+ message.deviceToken = null
+ expect(() => pushNotificationsService.processSetDeviceInfo(createInboundMessageContext(message))).not.toThrow(
+ PushNotificationsFcmProblemReportError
+ )
+
+ message.devicePlatform = 'something'
+ expect(() => pushNotificationsService.processSetDeviceInfo(createInboundMessageContext(message))).toThrow(
+ PushNotificationsFcmProblemReportError
+ )
})
})
})
+
+function createInboundMessageContext(message: T) {
+ return {
+ agentContext: new AgentContext({ dependencyManager: new DependencyManager(), contextCorrelationId: '' }),
+ message,
+ assertReadyConnection: function (): ConnectionRecord {
+ throw new Error('Function not implemented.')
+ },
+ toJSON: function (): {
+ message: T
+ recipientKey: string | undefined
+ senderKey: string | undefined
+ sessionId: string | undefined
+ agentContext: { contextCorrelationId: string }
+ } {
+ throw new Error('Function not implemented.')
+ },
+ }
+}
From 93f08bbda74d3261f8f23cbb26fbaeffa3c14c82 Mon Sep 17 00:00:00 2001
From: Ariel Gentile
Date: Mon, 14 Aug 2023 18:41:27 -0300
Subject: [PATCH 2/2] fix: address PR review feedback
Signed-off-by: Ariel Gentile
---
packages/push-notifications/samples/sample.ts | 9 +++++++++
.../src/apns/PushNotificationsApnsApi.ts | 3 ++-
.../messages/PushNotificationsApnsDeviceInfoMessage.ts | 2 +-
.../PushNotificationsApnsGetDeviceInfoMessage.ts | 2 +-
.../src/fcm/PushNotificationsFcmApi.ts | 3 ++-
5 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/packages/push-notifications/samples/sample.ts b/packages/push-notifications/samples/sample.ts
index 9ee1e527..1bd01be0 100644
--- a/packages/push-notifications/samples/sample.ts
+++ b/packages/push-notifications/samples/sample.ts
@@ -17,6 +17,15 @@ const run = async () => {
// Gets the push notification device information located at the other agent behind the connection
await agent.modules.pushNotificationsApns.getDeviceInfo('a-valid-connection')
+
+ // Sends device info as response from a get-device-info message
+ await agent.modules.pushNotificationsApns.deviceInfo({
+ connectionId: 'a-valid-connection',
+ threadId: 'get-device-info-msg-id',
+ deviceInfo: {
+ deviceToken: '123',
+ },
+ })
}
void run()
diff --git a/packages/push-notifications/src/apns/PushNotificationsApnsApi.ts b/packages/push-notifications/src/apns/PushNotificationsApnsApi.ts
index e6e639db..0c48dcbd 100644
--- a/packages/push-notifications/src/apns/PushNotificationsApnsApi.ts
+++ b/packages/push-notifications/src/apns/PushNotificationsApnsApi.ts
@@ -57,7 +57,8 @@ export class PushNotificationsApnsApi {
* @param deviceInfo The APNS device info
* @returns Promise
*/
- public async deviceInfo(connectionId: string, threadId: string, deviceInfo: ApnsDeviceInfo) {
+ public async deviceInfo(options: { connectionId: string; threadId: string; deviceInfo: ApnsDeviceInfo }) {
+ const { connectionId, threadId, deviceInfo } = options
const connection = await this.connectionService.getById(this.agentContext, connectionId)
connection.assertReady()
diff --git a/packages/push-notifications/src/apns/messages/PushNotificationsApnsDeviceInfoMessage.ts b/packages/push-notifications/src/apns/messages/PushNotificationsApnsDeviceInfoMessage.ts
index aa1d2f0e..0d77e334 100644
--- a/packages/push-notifications/src/apns/messages/PushNotificationsApnsDeviceInfoMessage.ts
+++ b/packages/push-notifications/src/apns/messages/PushNotificationsApnsDeviceInfoMessage.ts
@@ -13,7 +13,7 @@ interface PushNotificationsApnsDeviceInfoOptions extends ApnsDeviceInfo {
* Message to send the apns device information from another agent for push notifications
* This is used as a response for the `get-device-info` message
*
- * @todo @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#device-info
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#device-info
*/
export class PushNotificationsApnsDeviceInfoMessage extends AgentMessage {
public constructor(options: PushNotificationsApnsDeviceInfoOptions) {
diff --git a/packages/push-notifications/src/apns/messages/PushNotificationsApnsGetDeviceInfoMessage.ts b/packages/push-notifications/src/apns/messages/PushNotificationsApnsGetDeviceInfoMessage.ts
index d4bfb64d..d75a3bab 100644
--- a/packages/push-notifications/src/apns/messages/PushNotificationsApnsGetDeviceInfoMessage.ts
+++ b/packages/push-notifications/src/apns/messages/PushNotificationsApnsGetDeviceInfoMessage.ts
@@ -7,7 +7,7 @@ interface PushNotificationsApnsGetDeviceInfoOptions {
/**
* Message to get the apns device information from another agent for push notifications
*
- * @todo @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#get-device-info
+ * @see https://github.com/hyperledger/aries-rfcs/tree/main/features/0699-push-notifications-apns#get-device-info
*/
export class PushNotificationsApnsGetDeviceInfoMessage extends AgentMessage {
public constructor(options: PushNotificationsApnsGetDeviceInfoOptions) {
diff --git a/packages/push-notifications/src/fcm/PushNotificationsFcmApi.ts b/packages/push-notifications/src/fcm/PushNotificationsFcmApi.ts
index 3c1aceed..a8271596 100644
--- a/packages/push-notifications/src/fcm/PushNotificationsFcmApi.ts
+++ b/packages/push-notifications/src/fcm/PushNotificationsFcmApi.ts
@@ -58,7 +58,8 @@ export class PushNotificationsFcmApi {
* @param deviceInfo The FCM device info
* @returns Promise
*/
- public async deviceInfo(connectionId: string, threadId: string, deviceInfo: FcmDeviceInfo) {
+ public async deviceInfo(options: { connectionId: string; threadId: string; deviceInfo: FcmDeviceInfo }) {
+ const { connectionId, threadId, deviceInfo } = options
const connection = await this.connectionService.getById(this.agentContext, connectionId)
connection.assertReady()