mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) move apiserver tests to core, disentangling notifier+billing parts
Summary: This moves some more tests to core that would be useful for ANCT, which had been stuck in grist-saas due to some entanglements with sendgrid and billing. For sendgrid, I've moved around just enough material to permit the tests to run mostly unchanged. Ideally the interface to a notification system would be generalized, but that's a bigger project. Test Plan: checked that tests are likely to run as expected in core using preview laid out by ./buildtools/build_core.sh Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D4149
This commit is contained in:
173
app/gen-server/lib/NotifierTypes.ts
Normal file
173
app/gen-server/lib/NotifierTypes.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
*
|
||||
* Grist notifications are currently half-baked.
|
||||
* There is a sendgrid based implementation for Grist Lab's SaaS, but
|
||||
* nothing self-hostable yet.
|
||||
*
|
||||
*/
|
||||
|
||||
import {FullUser} from 'app/common/LoginSessionAPI';
|
||||
import {StringUnion} from 'app/common/StringUnion';
|
||||
|
||||
/**
|
||||
* Structure of sendgrid email requests. Each request references a template
|
||||
* (stored on sendgrid site) and a list of people to send a copy of that template
|
||||
* to, along with the relevant values to use for template variables.
|
||||
*/
|
||||
export interface SendGridMail {
|
||||
personalizations: SendGridPersonalization[];
|
||||
from: SendGridAddress;
|
||||
reply_to: SendGridAddress;
|
||||
template_id: string;
|
||||
asm?: { // unsubscribe settings
|
||||
group_id: number;
|
||||
};
|
||||
mail_settings?: {
|
||||
bypass_list_management?: {
|
||||
enable: boolean;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface SendGridContact {
|
||||
contacts: [{
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
custom_fields?: Record<string, any>;
|
||||
}],
|
||||
list_ids?: string[];
|
||||
}
|
||||
|
||||
export interface SendGridAddress {
|
||||
email: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SendGridPersonalization {
|
||||
to: SendGridAddress[];
|
||||
dynamic_template_data: {[key: string]: any};
|
||||
}
|
||||
|
||||
/**
|
||||
* Structure of sendgrid invite template. This is entirely under our control, it
|
||||
* is the information we choose to send to an email template for invites.
|
||||
*/
|
||||
|
||||
export interface SendGridInviteTemplate {
|
||||
user: FullUser;
|
||||
host: FullUser;
|
||||
resource: SendGridInviteResource;
|
||||
access: SendGridInviteAccess;
|
||||
}
|
||||
|
||||
export interface SendGridInviteResource {
|
||||
kind: SendGridInviteResourceKind;
|
||||
kindUpperFirst: string;
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export type SendGridInviteResourceKind = 'team site' | 'workspace' | 'document';
|
||||
|
||||
export interface SendGridInviteAccess {
|
||||
role: string;
|
||||
canEditAccess?: boolean;
|
||||
canEdit?: boolean;
|
||||
canView?: boolean;
|
||||
canManageBilling?: boolean;
|
||||
}
|
||||
|
||||
// Common parameters included in emails to active billing managers.
|
||||
export interface SendGridBillingTemplate {
|
||||
org: {id: number, name: string};
|
||||
orgUrl: string;
|
||||
billingUrl: string;
|
||||
}
|
||||
|
||||
export interface SendGridMemberChangeTemplate extends SendGridBillingTemplate {
|
||||
initiatingUser: FullUser;
|
||||
added: FullUser[];
|
||||
removed: FullUser[];
|
||||
org: {id: number, name: string};
|
||||
countBefore: number;
|
||||
countAfter: number;
|
||||
orgUrl: string;
|
||||
billingUrl: string;
|
||||
paidPlan: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format of sendgrid responses when looking up a user by email address using
|
||||
* SENDGRID.search
|
||||
*/
|
||||
export interface SendGridSearchResult {
|
||||
contact_count: number;
|
||||
result: SendGridSearchHit[];
|
||||
}
|
||||
|
||||
export interface SendGridSearchHit {
|
||||
id: string;
|
||||
email: string;
|
||||
list_ids: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative format of sendgrid responses when looking up a user by email
|
||||
* address using SENDGRID.searchByEmail
|
||||
* https://docs.sendgrid.com/api-reference/contacts/get-contacts-by-emails
|
||||
*/
|
||||
export interface SendGridSearchResultVariant {
|
||||
result: Record<string, SendGridSearchPossibleHit>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Documentation is contradictory on format of results when contacts not found, but if
|
||||
* something is found there should be a contact field.
|
||||
*/
|
||||
export interface SendGridSearchPossibleHit {
|
||||
contact?: SendGridSearchHit;
|
||||
}
|
||||
|
||||
export interface SendGridConfig {
|
||||
address: {
|
||||
from: {
|
||||
email: string;
|
||||
name: string;
|
||||
}
|
||||
},
|
||||
template: {
|
||||
invite?: string;
|
||||
billingManagerInvite?: string;
|
||||
memberChange?: string;
|
||||
trialPeriodEndingSoon?: string;
|
||||
twoFactorMethodAdded?: string;
|
||||
twoFactorMethodRemoved?: string;
|
||||
twoFactorPhoneNumberChanged?: string;
|
||||
twoFactorEnabled?: string;
|
||||
twoFactorDisabled?: string;
|
||||
},
|
||||
list: {
|
||||
singleUserOnboarding?: string;
|
||||
appSumoSignUps?: string;
|
||||
trial?: string;
|
||||
},
|
||||
unsubscribeGroup: {
|
||||
invites?: number;
|
||||
billingManagers?: number;
|
||||
},
|
||||
field?: {
|
||||
callScheduled?: string;
|
||||
userRef?: string;
|
||||
},
|
||||
}
|
||||
|
||||
export const TwoFactorEvents = StringUnion(
|
||||
'twoFactorMethodAdded',
|
||||
'twoFactorMethodRemoved',
|
||||
'twoFactorPhoneNumberChanged',
|
||||
'twoFactorEnabled',
|
||||
'twoFactorDisabled',
|
||||
);
|
||||
|
||||
export type TwoFactorEvent = typeof TwoFactorEvents.type;
|
||||
@@ -97,6 +97,7 @@ export function makeSimpleCreator(opts: {
|
||||
return notifier?.create(dbManager, gristConfig) ?? {
|
||||
get testPending() { return false; },
|
||||
async deleteUser() { /* do nothing */ },
|
||||
testSetSendMessageCallback() { return undefined; },
|
||||
};
|
||||
},
|
||||
ExternalStorage(purpose, extraPrefix) {
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import {SendGridConfig, SendGridMail} from 'app/gen-server/lib/NotifierTypes';
|
||||
|
||||
export interface INotifier {
|
||||
// for test purposes, check if any notifications are in progress
|
||||
readonly testPending: boolean;
|
||||
|
||||
deleteUser(userId: number): Promise<void>;
|
||||
|
||||
// Intercept outgoing messages for test purposes.
|
||||
// Return undefined if no notification system is available.
|
||||
testSetSendMessageCallback(op: (body: SendGridMail, description: string) => Promise<void>): SendGridConfig|undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user