Skip to content

Commit

Permalink
chore(notification): expose email mutations via grpc (#4011)
Browse files Browse the repository at this point in the history
* chore(notification): expose email mutations via grpc

* chore(core): bump notifications proto

* chore(core): add update / remove EmailAddress to notifications client

* chore(core): sync email address to notifications\

---------

Co-authored-by: Sam Peters <[email protected]>
  • Loading branch information
bodymindarts and UncleSamtoshi authored Feb 16, 2024
1 parent f8b75bc commit e720ff1
Show file tree
Hide file tree
Showing 14 changed files with 3,055 additions and 10 deletions.
8 changes: 8 additions & 0 deletions core/api/src/app/authentication/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AccountAlreadyHasEmailError } from "@/domain/authentication/errors"
import { AuthWithEmailPasswordlessService } from "@/services/kratos"
import { baseLogger } from "@/services/logger"
import { UsersRepository } from "@/services/mongoose"
import { NotificationsService } from "@/services/notifications"

export const addEmailToIdentity = async ({
email,
Expand Down Expand Up @@ -47,6 +48,11 @@ export const verifyEmail = async ({
})
if (res instanceof Error) return res

await NotificationsService().updateEmailAddress({
userId: res.kratosUserId,
email: res.email,
})

const user = await UsersRepository().findById(res.kratosUserId)
if (user instanceof Error) return user

Expand Down Expand Up @@ -74,5 +80,7 @@ export const removeEmail = async ({
})
if (updatedUser instanceof Error) return updatedUser

await NotificationsService().removeEmailAddress({ userId })

return user
}
7 changes: 7 additions & 0 deletions core/api/src/domain/notifications/index.types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,11 @@ interface INotificationsService {
userId: UserId
deviceToken: DeviceToken
}): Promise<NotificationSettings | NotificationsServiceError>

updateEmailAddress(args: {
userId: UserId
email: EmailAddress
}): Promise<true | NotificationsServiceError>

removeEmailAddress(args: { userId: UserId }): Promise<true | NotificationsServiceError>
}
16 changes: 16 additions & 0 deletions core/api/src/services/notifications/grpc-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import {
AddPushDeviceTokenResponse,
RemovePushDeviceTokenRequest,
RemovePushDeviceTokenResponse,
UpdateEmailAddressRequest,
UpdateEmailAddressResponse,
RemoveEmailAddressRequest,
RemoveEmailAddressResponse,
} from "./proto/notifications_pb"

import { NOTIFICATIONS_HOST, NOTIFICATIONS_PORT } from "@/config"
Expand Down Expand Up @@ -89,3 +93,15 @@ export const removePushDeviceToken = promisify<
Metadata,
RemovePushDeviceTokenResponse
>(notificationsClient.removePushDeviceToken.bind(notificationsClient))

export const updateEmailAddress = promisify<
UpdateEmailAddressRequest,
Metadata,
UpdateEmailAddressResponse
>(notificationsClient.updateEmailAddress.bind(notificationsClient))

export const removeEmailAddress = promisify<
RemoveEmailAddressRequest,
Metadata,
RemoveEmailAddressResponse
>(notificationsClient.removeEmailAddress.bind(notificationsClient))
47 changes: 47 additions & 0 deletions core/api/src/services/notifications/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
EnableNotificationChannelRequest,
GetNotificationSettingsRequest,
RemovePushDeviceTokenRequest,
UpdateEmailAddressRequest,
RemoveEmailAddressRequest,
UpdateUserLocaleRequest,
} from "./proto/notifications_pb"

Expand Down Expand Up @@ -478,6 +480,49 @@ export const NotificationsService = (): INotificationsService => {
}
}

const updateEmailAddress = async ({
userId,
email,
}: {
userId: UserId
email: EmailAddress
}): Promise<true | NotificationsServiceError> => {
try {
const request = new UpdateEmailAddressRequest()
request.setUserId(userId)
request.setEmailAddress(email)

await notificationsGrpc.updateEmailAddress(
request,
notificationsGrpc.notificationsMetadata,
)

return true
} catch (err) {
return new UnknownNotificationsServiceError(err)
}
}

const removeEmailAddress = async ({
userId,
}: {
userId: UserId
}): Promise<true | NotificationsServiceError> => {
try {
const request = new RemoveEmailAddressRequest()
request.setUserId(userId)

await notificationsGrpc.removeEmailAddress(
request,
notificationsGrpc.notificationsMetadata,
)

return true
} catch (err) {
return new UnknownNotificationsServiceError(err)
}
}

const updateUserLanguage = async ({
userId,
language,
Expand Down Expand Up @@ -653,6 +698,8 @@ export const NotificationsService = (): INotificationsService => {
enableNotificationCategory,
disableNotificationCategory,
addPushDeviceToken,
updateEmailAddress,
removeEmailAddress,
removePushDeviceToken,
},
}),
Expand Down
74 changes: 74 additions & 0 deletions core/api/src/services/notifications/proto/notifications.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ service NotificationsService {
rpc UpdateUserLocale (UpdateUserLocaleRequest) returns (UpdateUserLocaleResponse) {}
rpc AddPushDeviceToken (AddPushDeviceTokenRequest) returns (AddPushDeviceTokenResponse) {}
rpc RemovePushDeviceToken (RemovePushDeviceTokenRequest) returns (RemovePushDeviceTokenResponse) {}
rpc UpdateEmailAddress (UpdateEmailAddressRequest) returns (UpdateEmailAddressResponse) {}
rpc RemoveEmailAddress (RemoveEmailAddressRequest) returns (RemoveEmailAddressResponse) {}
rpc HandleNotificationEvent (HandleNotificationEventRequest) returns (HandleNotificationEventResponse) {}
}

enum NotificationChannel {
Expand Down Expand Up @@ -121,3 +124,74 @@ message RemovePushDeviceTokenRequest {
message RemovePushDeviceTokenResponse {
NotificationSettings notification_settings = 1;
}

message UpdateEmailAddressRequest {
string user_id = 1;
string email_address = 2;
}

message UpdateEmailAddressResponse { }

message RemoveEmailAddressRequest {
string user_id = 1;
}

message RemoveEmailAddressResponse { }

message HandleNotificationEventRequest {
NotificationEvent event = 1;
}

message HandleNotificationEventResponse { }

message NotificationEvent {
oneof data {
CircleGrew circle_grew = 1;
CircleThresholdReached circle_threshold_reached = 2;
IdentityVerificationApproved identity_verification_approved = 3;
IdentityVerificationDeclined identity_verification_declined = 4;
IdentityVerificationReviewPending identity_verification_review_pending = 5;
}
}

enum CircleType {
INNER = 0;
OUTER = 1;
}

message CircleGrew {
string user_id = 1;
CircleType circle_type = 2;
uint32 this_month_circle_size = 3;
uint32 all_time_circle_size = 4;
}

enum CircleTimeFrame {
MONTH = 0;
ALL_TIME = 1;
}

message CircleThresholdReached {
string user_id = 1;
CircleType circle_type = 2;
CircleTimeFrame time_frame = 3;
uint32 threshold = 4;
}

message IdentityVerificationApproved {
string user_id = 1;
}

enum DeclinedReason {
DOCUMENTS_NOT_CLEAR = 0;
VERIFICATION_PHOTO_NOT_CLEAR = 1;
}

message IdentityVerificationDeclined {
string user_id = 1;
DeclinedReason declined_reason = 2;
}

message IdentityVerificationReviewPending {
string user_id = 1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ interface INotificationsServiceService extends grpc.ServiceDefinition<grpc.Untyp
updateUserLocale: INotificationsServiceService_IUpdateUserLocale;
addPushDeviceToken: INotificationsServiceService_IAddPushDeviceToken;
removePushDeviceToken: INotificationsServiceService_IRemovePushDeviceToken;
updateEmailAddress: INotificationsServiceService_IUpdateEmailAddress;
removeEmailAddress: INotificationsServiceService_IRemoveEmailAddress;
handleNotificationEvent: INotificationsServiceService_IHandleNotificationEvent;
}

interface INotificationsServiceService_IShouldSendNotification extends grpc.MethodDefinition<notifications_pb.ShouldSendNotificationRequest, notifications_pb.ShouldSendNotificationResponse> {
Expand Down Expand Up @@ -101,6 +104,33 @@ interface INotificationsServiceService_IRemovePushDeviceToken extends grpc.Metho
responseSerialize: grpc.serialize<notifications_pb.RemovePushDeviceTokenResponse>;
responseDeserialize: grpc.deserialize<notifications_pb.RemovePushDeviceTokenResponse>;
}
interface INotificationsServiceService_IUpdateEmailAddress extends grpc.MethodDefinition<notifications_pb.UpdateEmailAddressRequest, notifications_pb.UpdateEmailAddressResponse> {
path: "/services.notifications.v1.NotificationsService/UpdateEmailAddress";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<notifications_pb.UpdateEmailAddressRequest>;
requestDeserialize: grpc.deserialize<notifications_pb.UpdateEmailAddressRequest>;
responseSerialize: grpc.serialize<notifications_pb.UpdateEmailAddressResponse>;
responseDeserialize: grpc.deserialize<notifications_pb.UpdateEmailAddressResponse>;
}
interface INotificationsServiceService_IRemoveEmailAddress extends grpc.MethodDefinition<notifications_pb.RemoveEmailAddressRequest, notifications_pb.RemoveEmailAddressResponse> {
path: "/services.notifications.v1.NotificationsService/RemoveEmailAddress";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<notifications_pb.RemoveEmailAddressRequest>;
requestDeserialize: grpc.deserialize<notifications_pb.RemoveEmailAddressRequest>;
responseSerialize: grpc.serialize<notifications_pb.RemoveEmailAddressResponse>;
responseDeserialize: grpc.deserialize<notifications_pb.RemoveEmailAddressResponse>;
}
interface INotificationsServiceService_IHandleNotificationEvent extends grpc.MethodDefinition<notifications_pb.HandleNotificationEventRequest, notifications_pb.HandleNotificationEventResponse> {
path: "/services.notifications.v1.NotificationsService/HandleNotificationEvent";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<notifications_pb.HandleNotificationEventRequest>;
requestDeserialize: grpc.deserialize<notifications_pb.HandleNotificationEventRequest>;
responseSerialize: grpc.serialize<notifications_pb.HandleNotificationEventResponse>;
responseDeserialize: grpc.deserialize<notifications_pb.HandleNotificationEventResponse>;
}

export const NotificationsServiceService: INotificationsServiceService;

Expand All @@ -114,6 +144,9 @@ export interface INotificationsServiceServer extends grpc.UntypedServiceImplemen
updateUserLocale: grpc.handleUnaryCall<notifications_pb.UpdateUserLocaleRequest, notifications_pb.UpdateUserLocaleResponse>;
addPushDeviceToken: grpc.handleUnaryCall<notifications_pb.AddPushDeviceTokenRequest, notifications_pb.AddPushDeviceTokenResponse>;
removePushDeviceToken: grpc.handleUnaryCall<notifications_pb.RemovePushDeviceTokenRequest, notifications_pb.RemovePushDeviceTokenResponse>;
updateEmailAddress: grpc.handleUnaryCall<notifications_pb.UpdateEmailAddressRequest, notifications_pb.UpdateEmailAddressResponse>;
removeEmailAddress: grpc.handleUnaryCall<notifications_pb.RemoveEmailAddressRequest, notifications_pb.RemoveEmailAddressResponse>;
handleNotificationEvent: grpc.handleUnaryCall<notifications_pb.HandleNotificationEventRequest, notifications_pb.HandleNotificationEventResponse>;
}

export interface INotificationsServiceClient {
Expand Down Expand Up @@ -144,6 +177,15 @@ export interface INotificationsServiceClient {
removePushDeviceToken(request: notifications_pb.RemovePushDeviceTokenRequest, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemovePushDeviceTokenResponse) => void): grpc.ClientUnaryCall;
removePushDeviceToken(request: notifications_pb.RemovePushDeviceTokenRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemovePushDeviceTokenResponse) => void): grpc.ClientUnaryCall;
removePushDeviceToken(request: notifications_pb.RemovePushDeviceTokenRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemovePushDeviceTokenResponse) => void): grpc.ClientUnaryCall;
updateEmailAddress(request: notifications_pb.UpdateEmailAddressRequest, callback: (error: grpc.ServiceError | null, response: notifications_pb.UpdateEmailAddressResponse) => void): grpc.ClientUnaryCall;
updateEmailAddress(request: notifications_pb.UpdateEmailAddressRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: notifications_pb.UpdateEmailAddressResponse) => void): grpc.ClientUnaryCall;
updateEmailAddress(request: notifications_pb.UpdateEmailAddressRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: notifications_pb.UpdateEmailAddressResponse) => void): grpc.ClientUnaryCall;
removeEmailAddress(request: notifications_pb.RemoveEmailAddressRequest, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemoveEmailAddressResponse) => void): grpc.ClientUnaryCall;
removeEmailAddress(request: notifications_pb.RemoveEmailAddressRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemoveEmailAddressResponse) => void): grpc.ClientUnaryCall;
removeEmailAddress(request: notifications_pb.RemoveEmailAddressRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemoveEmailAddressResponse) => void): grpc.ClientUnaryCall;
handleNotificationEvent(request: notifications_pb.HandleNotificationEventRequest, callback: (error: grpc.ServiceError | null, response: notifications_pb.HandleNotificationEventResponse) => void): grpc.ClientUnaryCall;
handleNotificationEvent(request: notifications_pb.HandleNotificationEventRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: notifications_pb.HandleNotificationEventResponse) => void): grpc.ClientUnaryCall;
handleNotificationEvent(request: notifications_pb.HandleNotificationEventRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: notifications_pb.HandleNotificationEventResponse) => void): grpc.ClientUnaryCall;
}

export class NotificationsServiceClient extends grpc.Client implements INotificationsServiceClient {
Expand Down Expand Up @@ -175,4 +217,13 @@ export class NotificationsServiceClient extends grpc.Client implements INotifica
public removePushDeviceToken(request: notifications_pb.RemovePushDeviceTokenRequest, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemovePushDeviceTokenResponse) => void): grpc.ClientUnaryCall;
public removePushDeviceToken(request: notifications_pb.RemovePushDeviceTokenRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemovePushDeviceTokenResponse) => void): grpc.ClientUnaryCall;
public removePushDeviceToken(request: notifications_pb.RemovePushDeviceTokenRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemovePushDeviceTokenResponse) => void): grpc.ClientUnaryCall;
public updateEmailAddress(request: notifications_pb.UpdateEmailAddressRequest, callback: (error: grpc.ServiceError | null, response: notifications_pb.UpdateEmailAddressResponse) => void): grpc.ClientUnaryCall;
public updateEmailAddress(request: notifications_pb.UpdateEmailAddressRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: notifications_pb.UpdateEmailAddressResponse) => void): grpc.ClientUnaryCall;
public updateEmailAddress(request: notifications_pb.UpdateEmailAddressRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: notifications_pb.UpdateEmailAddressResponse) => void): grpc.ClientUnaryCall;
public removeEmailAddress(request: notifications_pb.RemoveEmailAddressRequest, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemoveEmailAddressResponse) => void): grpc.ClientUnaryCall;
public removeEmailAddress(request: notifications_pb.RemoveEmailAddressRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemoveEmailAddressResponse) => void): grpc.ClientUnaryCall;
public removeEmailAddress(request: notifications_pb.RemoveEmailAddressRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: notifications_pb.RemoveEmailAddressResponse) => void): grpc.ClientUnaryCall;
public handleNotificationEvent(request: notifications_pb.HandleNotificationEventRequest, callback: (error: grpc.ServiceError | null, response: notifications_pb.HandleNotificationEventResponse) => void): grpc.ClientUnaryCall;
public handleNotificationEvent(request: notifications_pb.HandleNotificationEventRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: notifications_pb.HandleNotificationEventResponse) => void): grpc.ClientUnaryCall;
public handleNotificationEvent(request: notifications_pb.HandleNotificationEventRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: notifications_pb.HandleNotificationEventResponse) => void): grpc.ClientUnaryCall;
}
Loading

0 comments on commit e720ff1

Please sign in to comment.