Merge branch 'next' into next-respect

This commit is contained in:
Chi Vinh Le
2018-10-04 19:15:00 +02:00
102 changed files with 13134 additions and 9240 deletions
@@ -0,0 +1,5 @@
import { RequestHandler } from "express";
export const adminHandler: RequestHandler = (req, res) => {
res.render("admin");
};
@@ -1,5 +0,0 @@
import { RequestHandler } from "express";
export const streamHandler: RequestHandler = (req, res) => {
res.render("stream");
};
@@ -9,7 +9,7 @@ export const nocacheMiddleware: RequestHandler = (req, res, next) => {
next();
};
export const cacheHeadersMiddleware = (duration: string): RequestHandler => {
export const cacheHeadersMiddleware = (duration?: string): RequestHandler => {
const maxAge = duration ? Math.floor(ms(duration) / 1000) : false;
if (!maxAge) {
return nocacheMiddleware;
-156
View File
@@ -1,156 +0,0 @@
import express from "express";
import passport from "passport";
import {
logoutHandler,
signupHandler,
} from "talk-server/app/handlers/auth/local";
import { streamHandler } from "talk-server/app/handlers/embed/stream";
import { apiErrorHandler } from "talk-server/app/middleware/error";
import { errorLogger } from "talk-server/app/middleware/logging";
import { wrapAuthn } from "talk-server/app/middleware/passport";
import tenantMiddleware from "talk-server/app/middleware/tenant";
import managementGraphMiddleware from "talk-server/graph/management/middleware";
import tenantGraphMiddleware from "talk-server/graph/tenant/middleware";
import {
cacheHeadersMiddleware,
nocacheMiddleware,
} from "talk-server/app/middleware/cacheHeaders";
import { AppOptions } from "./index";
import playground from "./middleware/playground";
async function createManagementRouter(app: AppOptions, options: RouterOptions) {
const router = express.Router();
// Management API
router.use(
"/graphql",
express.json(),
await managementGraphMiddleware(
app.schemas.management,
app.config,
app.mongo
)
);
return router;
}
async function createTenantRouter(app: AppOptions, options: RouterOptions) {
const router = express.Router();
// Tenant identification middleware.
router.use(tenantMiddleware({ cache: app.tenantCache }));
// Setup Passport middleware.
router.use(options.passport.initialize());
// Setup auth routes.
router.use("/auth", createNewAuthRouter(app, options));
// Tenant API
router.use(
"/graphql",
express.json(),
// Any users may submit their GraphQL requests with authentication, this
// middleware will unpack their user into the request.
options.passport.authenticate("jwt", { session: false }),
await tenantGraphMiddleware({
schema: app.schemas.tenant,
config: app.config,
mongo: app.mongo,
redis: app.redis,
queue: app.queue,
})
);
return router;
}
function createNewAuthRouter(app: AppOptions, options: RouterOptions) {
const router = express.Router();
// Mount the passport routes.
router.delete(
"/",
options.passport.authenticate("jwt", { session: false }),
logoutHandler({ redis: app.redis })
);
router.post(
"/local",
express.json(),
wrapAuthn(options.passport, app.signingConfig, "local")
);
router.post(
"/local/signup",
express.json(),
signupHandler({ db: app.mongo, signingConfig: app.signingConfig })
);
router.get("/oidc", wrapAuthn(options.passport, app.signingConfig, "oidc"));
router.get(
"/oidc/callback",
wrapAuthn(options.passport, app.signingConfig, "oidc")
);
return router;
}
async function createAPIRouter(app: AppOptions, options: RouterOptions) {
// Create a router.
const router = express.Router();
// Configure the tenant routes.
router.use("/tenant", await createTenantRouter(app, options));
// Configure the management routes.
router.use("/management", await createManagementRouter(app, options));
// General API error handler.
router.use(errorLogger);
router.use(apiErrorHandler);
return router;
}
export interface RouterOptions {
/**
* passport is the instance of the Authenticator that can be used to create
* and mount new authentication middleware.
*/
passport: passport.Authenticator;
}
export async function createRouter(app: AppOptions, options: RouterOptions) {
// Create a router.
const router = express.Router();
router.use("/api", nocacheMiddleware, await createAPIRouter(app, options));
if (app.config.get("env") === "development") {
// Tenant GraphiQL
router.get(
"/tenant/graphiql",
playground({
endpoint: "/api/tenant/graphql",
subscriptionEndpoint: "/api/tenant/live",
})
);
// Management GraphiQL
router.get(
"/management/graphiql",
playground({
endpoint: "/api/management/graphql",
subscriptionEndpoint: "/api/management/live",
})
);
}
// Handle the stream handler.
router.get("/embed/stream", cacheHeadersMiddleware("1h"), streamHandler);
return router;
}
+39
View File
@@ -0,0 +1,39 @@
import express from "express";
import { AppOptions } from "talk-server/app";
import {
logoutHandler,
signupHandler,
} from "talk-server/app/handlers/auth/local";
import { wrapAuthn } from "talk-server/app/middleware/passport";
import { RouterOptions } from "talk-server/app/router/types";
export function createNewAuthRouter(app: AppOptions, options: RouterOptions) {
const router = express.Router();
// Mount the passport routes.
router.delete(
"/",
options.passport.authenticate("jwt", { session: false }),
logoutHandler({ redis: app.redis })
);
router.post(
"/local",
express.json(),
wrapAuthn(options.passport, app.signingConfig, "local")
);
router.post(
"/local/signup",
express.json(),
signupHandler({ db: app.mongo, signingConfig: app.signingConfig })
);
router.get("/oidc", wrapAuthn(options.passport, app.signingConfig, "oidc"));
router.get(
"/oidc/callback",
wrapAuthn(options.passport, app.signingConfig, "oidc")
);
return router;
}
+34
View File
@@ -0,0 +1,34 @@
import express from "express";
import passport from "passport";
import { AppOptions } from "talk-server/app";
import { apiErrorHandler } from "talk-server/app/middleware/error";
import { errorLogger } from "talk-server/app/middleware/logging";
import { createManagementRouter } from "./management";
import { createTenantRouter } from "./tenant";
export interface RouterOptions {
/**
* passport is the instance of the Authenticator that can be used to create
* and mount new authentication middleware.
*/
passport: passport.Authenticator;
}
export async function createAPIRouter(app: AppOptions, options: RouterOptions) {
// Create a router.
const router = express.Router();
// Configure the tenant routes.
router.use("/tenant", await createTenantRouter(app, options));
// Configure the management routes.
router.use("/management", await createManagementRouter(app));
// General API error handler.
router.use(errorLogger);
router.use(apiErrorHandler);
return router;
}
@@ -0,0 +1,21 @@
import express from "express";
import { AppOptions } from "talk-server/app";
import managementGraphMiddleware from "talk-server/graph/management/middleware";
export async function createManagementRouter(app: AppOptions) {
const router = express.Router();
// Management API
router.use(
"/graphql",
express.json(),
await managementGraphMiddleware(
app.schemas.management,
app.config,
app.mongo
)
);
return router;
}
+42
View File
@@ -0,0 +1,42 @@
import express from "express";
import { AppOptions } from "talk-server/app";
import tenantMiddleware from "talk-server/app/middleware/tenant";
import { RouterOptions } from "talk-server/app/router/types";
import tenantGraphMiddleware from "talk-server/graph/tenant/middleware";
import { createNewAuthRouter } from "./auth";
export async function createTenantRouter(
app: AppOptions,
options: RouterOptions
) {
const router = express.Router();
// Tenant identification middleware.
router.use(tenantMiddleware({ cache: app.tenantCache }));
// Setup Passport middleware.
router.use(options.passport.initialize());
// Setup auth routes.
router.use("/auth", createNewAuthRouter(app, options));
// Tenant API
router.use(
"/graphql",
express.json(),
// Any users may submit their GraphQL requests with authentication, this
// middleware will unpack their user into the request.
options.passport.authenticate("jwt", { session: false }),
await tenantGraphMiddleware({
schema: app.schemas.tenant,
config: app.config,
mongo: app.mongo,
redis: app.redis,
queue: app.queue,
})
);
return router;
}
+29
View File
@@ -0,0 +1,29 @@
import express from "express";
import { cacheHeadersMiddleware } from "talk-server/app/middleware/cacheHeaders";
export interface ClientTargetHandlerOptions {
/**
* view is the name of the template to render.
*/
view: string;
/**
* cacheDuration is the cache duration that a given request should be cached for.
*/
cacheDuration?: string;
}
export function createClientTargetRouter({
view,
cacheDuration = "1h",
}: ClientTargetHandlerOptions) {
// Create a router.
const router = express.Router();
router.get("/", cacheHeadersMiddleware(cacheDuration), (req, res) =>
res.render(view)
);
return router;
}
+60
View File
@@ -0,0 +1,60 @@
import express, { Router } from "express";
import { AppOptions } from "talk-server/app";
import { nocacheMiddleware } from "talk-server/app/middleware/cacheHeaders";
import playground from "talk-server/app/middleware/playground";
import { RouterOptions } from "talk-server/app/router/types";
import logger from "talk-server/logger";
import { createAPIRouter } from "./api";
import { createClientTargetRouter } from "./client";
export async function createRouter(app: AppOptions, options: RouterOptions) {
// Create a router.
const router = express.Router();
router.use("/api", nocacheMiddleware, await createAPIRouter(app, options));
// Attach the GraphiQL if enabled.
if (app.config.get("enable_graphiql")) {
attachGraphiQL(router, app);
}
// Add the client targets.
router.get("/embed/stream", createClientTargetRouter({ view: "stream" }));
router.get("/admin", createClientTargetRouter({ view: "admin" }));
return router;
}
/**
* attachGraphiQL will attach the GraphiQL routes to the router.
*
* @param router the router to attach the GraphiQL routes to
* @param app the application to read the configuration from
*/
function attachGraphiQL(router: Router, app: AppOptions) {
if (app.config.get("env") === "production") {
logger.warn(
"enable_graphiql is enabled, but we're in production mode, this is not recommended"
);
}
// Tenant GraphiQL
router.get(
"/tenant/graphiql",
playground({
endpoint: "/api/tenant/graphql",
subscriptionEndpoint: "/api/tenant/live",
})
);
// Management GraphiQL
router.get(
"/management/graphiql",
playground({
endpoint: "/api/management/graphql",
subscriptionEndpoint: "/api/management/live",
})
);
}
+9
View File
@@ -0,0 +1,9 @@
import passport from "passport";
export interface RouterOptions {
/**
* passport is the instance of the Authenticator that can be used to create
* and mount new authentication middleware.
*/
passport: passport.Authenticator;
}