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

chore(notification): expose email mutations via grpc #4011

Merged
merged 5 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading