mirror of
https://github.com/wassname/talk.git
synced 2026-07-05 11:26:40 +08:00
84bbc3d0c3
* feat: initial impl * Create preliminary comment moderation slices CORL-688 * Move slices logic into stacks CORL-688 * Create user comment counts CORL-688 * Create naive mutation that initializes user comment counts CORL-688 * Use bulk updates in user counts migration CORL-688 * fix: review * fix: fixed issue with aggregation * Migrate creating comment into stacks CORL-688 * Migrate editing a comment to the stacks CORL-688 * Break publishing comment status out of updateAllCounts CORL-688 * review: removed variable scoping in favor of export * revert: feb8e8196cd448f5cd24f1ca2eb0b91fe9bd43c7 * review: simplification of stacks implementation This simplifies the stacks implementation to better reuse code related to count management and event publishing. This can be used to great effect with the upcomming events PR #2738. * Consolidate the tenant and common context together CORL-688 * review: removed variable scoping in favor of export * revert: feb8e8196cd448f5cd24f1ca2eb0b91fe9bd43c7 * review: simplification of stacks implementation This simplifies the stacks implementation to better reuse code related to count management and event publishing. This can be used to great effect with the upcomming events PR #2738. * fix: check if authorID is null before update user counts CORL-688 * Consolidate common/tenant context supporting files CORL-688 * feat: renamed TenantContext -> GraphContext Co-authored-by: Wyatt Johnson <accounts+github@wyattjoh.ca>
96 lines
2.2 KiB
TypeScript
96 lines
2.2 KiB
TypeScript
import { Db } from "mongodb";
|
|
import uuid from "uuid";
|
|
|
|
import { Omit, Sub } from "coral-common/types";
|
|
import { GQLUSER_ROLE } from "coral-server/graph/schema/__generated__/types";
|
|
import { TenantResource } from "coral-server/models/tenant";
|
|
import { invites as collection } from "coral-server/services/mongodb/collections";
|
|
|
|
export interface Invite extends TenantResource {
|
|
readonly id: string;
|
|
email: string;
|
|
role: GQLUSER_ROLE;
|
|
expiresAt: Date;
|
|
createdBy: string;
|
|
createdAt: Date;
|
|
}
|
|
|
|
export type CreateInviteInput = Omit<
|
|
Invite,
|
|
"id" | "createdAt" | "tenantID" | "createdBy"
|
|
>;
|
|
|
|
export async function createInvite(
|
|
mongo: Db,
|
|
tenantID: string,
|
|
{ email, ...input }: CreateInviteInput,
|
|
createdBy: string,
|
|
now = new Date()
|
|
) {
|
|
// Create an ID for the Invite.
|
|
const id = uuid.v4();
|
|
|
|
// defaults are the properties set by the application when a new Invite is
|
|
// created.
|
|
const defaults: Sub<Invite, CreateInviteInput> = {
|
|
id,
|
|
tenantID,
|
|
createdBy,
|
|
createdAt: now,
|
|
};
|
|
|
|
// Merge the defaults and the input together.
|
|
const invite: Readonly<Invite> = {
|
|
...defaults,
|
|
...input,
|
|
email: email.toLowerCase(),
|
|
};
|
|
|
|
// Insert it into the database. This may throw an error.
|
|
await collection(mongo).insertOne(invite);
|
|
|
|
return invite;
|
|
}
|
|
|
|
export async function redeemInvite(mongo: Db, tenantID: string, id: string) {
|
|
// Try to snag the invite from the database safely.
|
|
const result = await collection(mongo).findOneAndDelete({ id, tenantID }, {});
|
|
if (!result.value) {
|
|
throw new Error("an unexpected error occurred");
|
|
}
|
|
|
|
return result.value;
|
|
}
|
|
|
|
export async function redeemInviteFromEmail(
|
|
mongo: Db,
|
|
tenantID: string,
|
|
email: string
|
|
) {
|
|
// Try to snag the invite from the database safely.
|
|
const result = await collection(mongo).findOneAndDelete(
|
|
{ email, tenantID },
|
|
{}
|
|
);
|
|
|
|
return result.value || null;
|
|
}
|
|
|
|
export async function retrieveInviteFromEmail(
|
|
mongo: Db,
|
|
tenantID: string,
|
|
email: string
|
|
) {
|
|
return collection(mongo).findOne({
|
|
tenantID,
|
|
email: email.toLowerCase(),
|
|
});
|
|
}
|
|
|
|
export async function retrieveInvite(mongo: Db, tenantID: string, id: string) {
|
|
return collection(mongo).findOne({
|
|
tenantID,
|
|
id,
|
|
});
|
|
}
|