[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:
Wyatt Johnson
2018-09-04 18:47:20 +00:00
committed by GitHub
parent 76d198f2a6
commit 59cf728681
46 changed files with 1804 additions and 377 deletions
+12 -4
View File
@@ -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 }
+46 -120
View File
@@ -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.
+25 -5
View File
@@ -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 }