mirror of
https://github.com/wassname/talk.git
synced 2026-09-09 11:38:08 +08:00
[next] Tasks (#1777)
* feat: initial support for synced tenants * fix: cleanup * fix: logger now respects logging level * fix: cache now ignores updates issued from itself * feat: print subscriber count * feat: initial moderation + validation for new comments * fix: added Promiseable type * feat: initial actions impl * feat: more moderation phases * fix: handle settings inheritence * fix: moved settings into new file * fix: defaults and documentation * fix: replace merge with object spread * feat: added integration with akismet * fix: support tenant cache for oidc strategy * fix: fixed compile * fix: import ordering * feat: added bull for queue support * feat: support for scraping * fix: fixes for scraper - Implemented simple metascraper replacement (to resolve security advisory warning) - Implemented simle dotize replacement (to resolve not working version that couldn't handle date objects) - Plugged in asset scraping to asset creation process * fix: handles array values * feat: added initial scraper implementation * feat: seperate queues but share config * fix: simplified auth data access * feat: moved more settings into the graph * feat: improved mailer design * fix: fixed issue with dotize * fix: fixed some issues with adapter * fix: queue cleanup * feat: added organizationName to Tenant * feat: email rendering * review: support es6 imports * fix: restore old ci step * fix: adjusted logging messages
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import dotize from "dotize";
|
||||
import { defaults } from "lodash";
|
||||
import { Db } from "mongodb";
|
||||
import uuid from "uuid";
|
||||
|
||||
import { Omit } from "talk-common/types";
|
||||
import { dotize } from "talk-common/utils/dotize";
|
||||
import { ModerationSettings } from "talk-server/models/settings";
|
||||
import { TenantResource } from "talk-server/models/tenant";
|
||||
|
||||
@@ -172,12 +172,20 @@ export async function updateAsset(
|
||||
db: Db,
|
||||
tenantID: string,
|
||||
id: string,
|
||||
update: UpdateAssetInput
|
||||
input: UpdateAssetInput
|
||||
) {
|
||||
// Only update fields that have been updated.
|
||||
const update = {
|
||||
$set: {
|
||||
...dotize(input, { embedArrays: true }),
|
||||
// Always update the updated at time.
|
||||
updated_at: new Date(),
|
||||
},
|
||||
};
|
||||
|
||||
const result = await collection(db).findOneAndUpdate(
|
||||
{ id, tenant_id: tenantID },
|
||||
// Only update fields that have been updated.
|
||||
{ $set: dotize.convert(update) },
|
||||
update,
|
||||
// False to return the updated document instead of the original
|
||||
// document.
|
||||
{ returnOriginal: false }
|
||||
|
||||
@@ -1,132 +1,52 @@
|
||||
import {
|
||||
GQLAuth,
|
||||
GQLEmail,
|
||||
GQLExternalIntegrations,
|
||||
GQLKarma,
|
||||
GQLMODERATION_MODE,
|
||||
GQLUSER_ROLE,
|
||||
GQLWordlist,
|
||||
} from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
|
||||
export interface EmailDomainRuleCondition {
|
||||
/**
|
||||
* emailDomain is the domain name component of the email addresses that should
|
||||
* match for this condition.
|
||||
*/
|
||||
emailDomain: string;
|
||||
/**
|
||||
* emailVerifiedRequired stipulates that this rule only applies when the user
|
||||
* account has been marked as having their email address already verified.
|
||||
*/
|
||||
emailVerifiedRequired: boolean;
|
||||
}
|
||||
// export interface EmailDomainRuleCondition {
|
||||
// /**
|
||||
// * emailDomain is the domain name component of the email addresses that should
|
||||
// * match for this condition.
|
||||
// */
|
||||
// emailDomain: string;
|
||||
// /**
|
||||
// * emailVerifiedRequired stipulates that this rule only applies when the user
|
||||
// * account has been marked as having their email address already verified.
|
||||
// */
|
||||
// emailVerifiedRequired: boolean;
|
||||
// }
|
||||
|
||||
/**
|
||||
* RoleRule describes the role assignment for when a user logs into Talk, how
|
||||
* they can have their account automatically upgraded to a specific role when
|
||||
* the domain for their email matches the one provided.
|
||||
*/
|
||||
export interface RoleRule extends Partial<EmailDomainRuleCondition> {
|
||||
/**
|
||||
* role is the specific GQLUSER_ROLE that should be assigned to the newly
|
||||
* created user depending on their email address.
|
||||
*/
|
||||
role: GQLUSER_ROLE;
|
||||
}
|
||||
// /**
|
||||
// * RoleRule describes the role assignment for when a user logs into Talk, how
|
||||
// * they can have their account automatically upgraded to a specific role when
|
||||
// * the domain for their email matches the one provided.
|
||||
// */
|
||||
// export interface RoleRule extends Partial<EmailDomainRuleCondition> {
|
||||
// /**
|
||||
// * role is the specific GQLUSER_ROLE that should be assigned to the newly
|
||||
// * created user depending on their email address.
|
||||
// */
|
||||
// role: GQLUSER_ROLE;
|
||||
// }
|
||||
|
||||
export interface AuthRules {
|
||||
/**
|
||||
* roles allow the configuration of automatic role assignment based on the
|
||||
* user's email address.
|
||||
*/
|
||||
roles?: RoleRule[];
|
||||
// export interface AuthRules {
|
||||
// /**
|
||||
// * roles allow the configuration of automatic role assignment based on the
|
||||
// * user's email address.
|
||||
// */
|
||||
// roles?: RoleRule[];
|
||||
|
||||
/**
|
||||
* restrictTo when populated, will restrict which users can login using this
|
||||
* integration. If a user successfully logs in using the OIDCStrategy, but
|
||||
* does not match the following rules, the user will not be created.
|
||||
*/
|
||||
restrictTo?: EmailDomainRuleCondition[];
|
||||
}
|
||||
|
||||
export interface EnableableIntegration {
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export interface DisplayNameAuthIntegration {
|
||||
displayNameEnable: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* SSOAuthIntegration is an AuthIntegration that provides a secret to the admins
|
||||
* of a tenant, where they can sign a SSO payload with it to provide to the
|
||||
* embed to allow single sign on.
|
||||
*/
|
||||
export interface SSOAuthIntegration
|
||||
extends EnableableIntegration,
|
||||
DisplayNameAuthIntegration {
|
||||
key: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* OIDCAuthIntegration provides a way to store Open ID Connect credentials. This
|
||||
* will be used in the admin to provide staff logins for users.
|
||||
*/
|
||||
export interface OIDCAuthIntegration
|
||||
extends EnableableIntegration,
|
||||
DisplayNameAuthIntegration {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
issuer: string;
|
||||
authorizationURL: string;
|
||||
jwksURI: string;
|
||||
tokenURL: string;
|
||||
}
|
||||
|
||||
export interface FacebookAuthIntegration extends EnableableIntegration {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
}
|
||||
|
||||
export interface GoogleAuthIntegration extends EnableableIntegration {
|
||||
clientID: string;
|
||||
clientSecret: string;
|
||||
}
|
||||
|
||||
export type LocalAuthIntegration = EnableableIntegration;
|
||||
|
||||
/**
|
||||
* AuthIntegrations describes all of the possible auth integration
|
||||
* configurations.
|
||||
*/
|
||||
export interface AuthIntegrations {
|
||||
/**
|
||||
* local is the auth integration for the email/password based auth.
|
||||
*/
|
||||
local: LocalAuthIntegration;
|
||||
|
||||
/**
|
||||
* sso is the external auth integration for the single sign on auth.
|
||||
*/
|
||||
sso?: SSOAuthIntegration;
|
||||
|
||||
/**
|
||||
* sso is the external auth integration for the OpenID Connect auth.
|
||||
*/
|
||||
oidc?: OIDCAuthIntegration;
|
||||
|
||||
/**
|
||||
* sso is the external auth integration for the Google auth.
|
||||
*/
|
||||
google?: GoogleAuthIntegration;
|
||||
|
||||
/**
|
||||
* sso is the external auth integration for the Facebook auth.
|
||||
*/
|
||||
facebook?: FacebookAuthIntegration;
|
||||
}
|
||||
|
||||
export interface Auth {
|
||||
integrations: AuthIntegrations;
|
||||
}
|
||||
// /**
|
||||
// * restrictTo when populated, will restrict which users can login using this
|
||||
// * integration. If a user successfully logs in using the OIDCStrategy, but
|
||||
// * does not match the following rules, the user will not be created.
|
||||
// */
|
||||
// restrictTo?: EmailDomainRuleCondition[];
|
||||
// }
|
||||
|
||||
export interface ModerationSettings {
|
||||
moderation: GQLMODERATION_MODE;
|
||||
@@ -155,6 +75,12 @@ export interface Settings extends ModerationSettings {
|
||||
*/
|
||||
editCommentWindowLength: number;
|
||||
|
||||
/**
|
||||
* email is the set of credentials and settings associated with the
|
||||
* Tenant.
|
||||
*/
|
||||
email: GQLEmail;
|
||||
|
||||
/**
|
||||
* karma is the set of settings related to how user Trust and Karma are
|
||||
* handled.
|
||||
@@ -169,7 +95,7 @@ export interface Settings extends ModerationSettings {
|
||||
/**
|
||||
* Set of configured authentication integrations.
|
||||
*/
|
||||
auth: Auth;
|
||||
auth: GQLAuth;
|
||||
|
||||
/**
|
||||
* Various integrations with external services.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import dotize from "dotize";
|
||||
import { Db } from "mongodb";
|
||||
import uuid from "uuid";
|
||||
|
||||
import { Omit, Sub } from "talk-common/types";
|
||||
import { DeepPartial, Omit, Sub } from "talk-common/types";
|
||||
import { dotize } from "talk-common/utils/dotize";
|
||||
import { GQLMODERATION_MODE } from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
import { Settings } from "talk-server/models/settings";
|
||||
|
||||
@@ -28,6 +28,7 @@ export interface Tenant extends Settings {
|
||||
domains: string[];
|
||||
|
||||
organizationName: string;
|
||||
organizationURL: string;
|
||||
organizationContactEmail: string;
|
||||
}
|
||||
|
||||
@@ -38,7 +39,11 @@ export interface Tenant extends Settings {
|
||||
*/
|
||||
export type CreateTenantInput = Pick<
|
||||
Tenant,
|
||||
"domain" | "organizationName" | "organizationContactEmail" | "domains"
|
||||
| "domain"
|
||||
| "organizationName"
|
||||
| "organizationURL"
|
||||
| "organizationContactEmail"
|
||||
| "domains"
|
||||
>;
|
||||
|
||||
/**
|
||||
@@ -76,8 +81,23 @@ export async function createTenant(db: Db, input: CreateTenantInput) {
|
||||
local: {
|
||||
enabled: true,
|
||||
},
|
||||
sso: {
|
||||
enabled: false,
|
||||
},
|
||||
oidc: {
|
||||
enabled: false,
|
||||
},
|
||||
google: {
|
||||
enabled: false,
|
||||
},
|
||||
facebook: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
email: {
|
||||
enabled: false,
|
||||
},
|
||||
karma: {
|
||||
enabled: true,
|
||||
thresholds: {
|
||||
@@ -149,7 +169,7 @@ export async function retrieveAllTenants(db: Db) {
|
||||
.toArray();
|
||||
}
|
||||
|
||||
export type UpdateTenantInput = Omit<Partial<Tenant>, "id" | "domain">;
|
||||
export type UpdateTenantInput = Omit<DeepPartial<Tenant>, "id" | "domain">;
|
||||
|
||||
export async function updateTenant(
|
||||
db: Db,
|
||||
@@ -160,7 +180,7 @@ export async function updateTenant(
|
||||
const result = await collection(db).findOneAndUpdate(
|
||||
{ id },
|
||||
// Only update fields that have been updated.
|
||||
{ $set: dotize.convert(update) },
|
||||
{ $set: dotize(update, { embedArrays: true }) },
|
||||
// False to return the updated document instead of the original
|
||||
// document.
|
||||
{ returnOriginal: false }
|
||||
|
||||
Reference in New Issue
Block a user