mirror of
https://github.com/wassname/talk.git
synced 2026-08-04 13:23:35 +08:00
Merge branch 'next-profile' of https://github.com/coralproject/talk into next-profile
This commit is contained in:
@@ -239,6 +239,22 @@ export default function createWebpackConfig({
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: paths.appAdminLocalesTemplate,
|
||||
use: [
|
||||
// This is the locales loader that loads available locales
|
||||
// from a particular target.
|
||||
{
|
||||
loader: "locales-loader",
|
||||
options: {
|
||||
...localesOptions,
|
||||
// Target specifies the prefix for fluent files to be loaded.
|
||||
// ${target}-xyz.ftl and ${†arget}.ftl are loaded into the locales.
|
||||
target: "admin",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Loader for our fluent files.
|
||||
{
|
||||
test: /\.ftl$/,
|
||||
@@ -416,6 +432,12 @@ export default function createWebpackConfig({
|
||||
paths.appAuthIndex,
|
||||
// Remove deactivated entries.
|
||||
],
|
||||
admin: [
|
||||
// We ship polyfills by default
|
||||
paths.appPolyfill,
|
||||
...devServerEntries,
|
||||
paths.appAdminIndex,
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
...baseConfig.plugins!,
|
||||
@@ -435,6 +457,14 @@ export default function createWebpackConfig({
|
||||
inject: "body",
|
||||
...htmlWebpackConfig,
|
||||
}),
|
||||
// Generates an `admin.html` file with the <script> injected.
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "admin.html",
|
||||
template: paths.appAdminHTML,
|
||||
chunks: ["admin"],
|
||||
inject: "body",
|
||||
...htmlWebpackConfig,
|
||||
}),
|
||||
// Makes some environment variables available in index.html.
|
||||
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
||||
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
|
||||
@@ -29,6 +29,10 @@ export default {
|
||||
appAuthLocalesTemplate: resolveSrc("core/client/auth/locales.ts"),
|
||||
appAuthIndex: resolveSrc("core/client/auth/index.tsx"),
|
||||
|
||||
appAdminHTML: resolveSrc("core/client/admin/index.html"),
|
||||
appAdminLocalesTemplate: resolveSrc("core/client/admin/locales.ts"),
|
||||
appAdminIndex: resolveSrc("core/client/admin/index.tsx"),
|
||||
|
||||
appEmbedIndex: resolveSrc("core/client/embed/index.ts"),
|
||||
appEmbedHTML: resolveSrc("core/client/embed/index.html"),
|
||||
appEmbedArticleHTML: resolveSrc("core/client/embed/article.html"),
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
const path = require("path");
|
||||
module.exports = {
|
||||
extends: "../.babelrc.js",
|
||||
plugins: [
|
||||
[
|
||||
"babel-plugin-relay",
|
||||
{ artifactDirectory: path.resolve(__dirname, "./__generated__") },
|
||||
],
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
.root {
|
||||
width: 1080px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { HorizontalGutter } from "talk-ui/components";
|
||||
import styles from "./App.css";
|
||||
import Navigation from "./Navigation";
|
||||
|
||||
const App: StatelessComponent = ({ children }) => (
|
||||
<HorizontalGutter className={styles.root}>
|
||||
<Navigation />
|
||||
{children}
|
||||
</HorizontalGutter>
|
||||
);
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,10 @@
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { HorizontalGutter, Typography } from "talk-ui/components";
|
||||
|
||||
const Community: StatelessComponent = ({ children }) => (
|
||||
<HorizontalGutter>
|
||||
<Typography variant="heading3">Community</Typography>
|
||||
</HorizontalGutter>
|
||||
);
|
||||
|
||||
export default Community;
|
||||
@@ -0,0 +1,10 @@
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { HorizontalGutter, Typography } from "talk-ui/components";
|
||||
|
||||
const Configure: StatelessComponent = ({ children }) => (
|
||||
<HorizontalGutter>
|
||||
<Typography variant="heading3">Configure</Typography>
|
||||
</HorizontalGutter>
|
||||
);
|
||||
|
||||
export default Configure;
|
||||
@@ -0,0 +1,10 @@
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { HorizontalGutter, Typography } from "talk-ui/components";
|
||||
|
||||
const Moderate: StatelessComponent = ({ children }) => (
|
||||
<HorizontalGutter>
|
||||
<Typography variant="heading3">Moderate</Typography>
|
||||
</HorizontalGutter>
|
||||
);
|
||||
|
||||
export default Moderate;
|
||||
@@ -0,0 +1,7 @@
|
||||
.link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.active {
|
||||
border-bottom: 3px solid var(--palette-primary-main);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Link } from "found";
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { Button, Flex, Typography } from "talk-ui/components";
|
||||
import styles from "./Navigation.css";
|
||||
|
||||
const Navigation: StatelessComponent = () => (
|
||||
<Flex itemGutter="double">
|
||||
<Typography variant="heading1">Talk</Typography>
|
||||
<Link
|
||||
to="/admin/moderate"
|
||||
className={styles.link}
|
||||
activeClassName={styles.active}
|
||||
>
|
||||
<Button>Moderate</Button>
|
||||
</Link>
|
||||
<Link
|
||||
to="/admin/community"
|
||||
className={styles.link}
|
||||
activeClassName={styles.active}
|
||||
>
|
||||
<Button>Community</Button>
|
||||
</Link>
|
||||
<Link
|
||||
to="/admin/stories"
|
||||
className={styles.link}
|
||||
activeClassName={styles.active}
|
||||
>
|
||||
<Button>Stories</Button>
|
||||
</Link>
|
||||
<Link
|
||||
to="/admin/configure"
|
||||
className={styles.link}
|
||||
activeClassName={styles.active}
|
||||
>
|
||||
<Button>Configure</Button>
|
||||
</Link>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
export default Navigation;
|
||||
@@ -0,0 +1,10 @@
|
||||
import React, { StatelessComponent } from "react";
|
||||
import { HorizontalGutter, Typography } from "talk-ui/components";
|
||||
|
||||
const Stories: StatelessComponent = ({ children }) => (
|
||||
<HorizontalGutter>
|
||||
<Typography variant="heading3">Stories</Typography>
|
||||
</HorizontalGutter>
|
||||
);
|
||||
|
||||
export default Stories;
|
||||
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Talk - Admin</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,40 @@
|
||||
import { BrowserProtocol, queryMiddleware } from "farce";
|
||||
import { createFarceRouter, createRender } from "found";
|
||||
import { Resolver } from "found-relay";
|
||||
|
||||
import React, { StatelessComponent } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { createManaged } from "talk-framework/lib/bootstrap";
|
||||
import { TalkContextConsumer } from "talk-framework/lib/bootstrap/TalkContext";
|
||||
import { initLocalState } from "./local";
|
||||
import localesData from "./locales";
|
||||
import routeConfig from "./routeConfig";
|
||||
|
||||
async function main() {
|
||||
const ManagedTalkContextProvider = await createManaged({
|
||||
initLocalState,
|
||||
localesData,
|
||||
userLocales: navigator.languages,
|
||||
});
|
||||
|
||||
const Router = createFarceRouter({
|
||||
historyProtocol: new BrowserProtocol(),
|
||||
historyMiddlewares: [queryMiddleware],
|
||||
routeConfig,
|
||||
render: createRender({}),
|
||||
});
|
||||
|
||||
const Index: StatelessComponent = () => (
|
||||
<ManagedTalkContextProvider>
|
||||
<TalkContextConsumer>
|
||||
{({ relayEnvironment }) => (
|
||||
<Router resolver={new Resolver(relayEnvironment)} />
|
||||
)}
|
||||
</TalkContextConsumer>
|
||||
</ManagedTalkContextProvider>
|
||||
);
|
||||
|
||||
ReactDOM.render(<Index />, document.getElementById("app"));
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1 @@
|
||||
export { default as initLocalState } from "./initLocalState";
|
||||
@@ -0,0 +1,21 @@
|
||||
import { commitLocalUpdate, Environment } from "relay-runtime";
|
||||
|
||||
import {
|
||||
createAndRetain,
|
||||
LOCAL_ID,
|
||||
LOCAL_TYPE,
|
||||
} from "talk-framework/lib/relay";
|
||||
|
||||
/**
|
||||
* Initializes the local state, before we start the App.
|
||||
*/
|
||||
export default async function initLocalState(environment: Environment) {
|
||||
commitLocalUpdate(environment, s => {
|
||||
const root = s.getRoot();
|
||||
|
||||
// Create the Local Record which is the Root for the client states.
|
||||
const localRecord = createAndRetain(environment, s, LOCAL_ID, LOCAL_TYPE);
|
||||
|
||||
root.setLinkedRecord(localRecord, "local");
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
type Local {}
|
||||
|
||||
extend type Query {
|
||||
local: Local!
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* The actual content of this file is being generated by our `locales-loader`.
|
||||
* Please check `./src/loaders` and the webpack config for more information.
|
||||
*
|
||||
* This file only represents the types that gets exported.
|
||||
*/
|
||||
|
||||
import { LocalesData } from "talk-framework/lib/i18n";
|
||||
export default {} as LocalesData;
|
||||
@@ -0,0 +1,17 @@
|
||||
import { makeRouteConfig, Route } from "found";
|
||||
import React from "react";
|
||||
|
||||
import App from "./components/App";
|
||||
import Community from "./components/Community";
|
||||
import Configure from "./components/Configure";
|
||||
import Moderate from "./components/Moderate";
|
||||
import Stories from "./components/Stories";
|
||||
|
||||
export default makeRouteConfig(
|
||||
<Route path="admin" Component={App}>
|
||||
<Route path="moderate" Component={Moderate} />
|
||||
<Route path="community" Component={Community} />
|
||||
<Route path="stories" Component={Stories} />
|
||||
<Route path="configure" Component={Configure} />
|
||||
</Route>
|
||||
);
|
||||
@@ -34,6 +34,13 @@ const config = convict({
|
||||
default: "development",
|
||||
env: "NODE_ENV",
|
||||
},
|
||||
enable_graphiql: {
|
||||
doc: "When true, this will enable the GraphiQL routes",
|
||||
format: Boolean,
|
||||
default: false,
|
||||
env: "ENABLE_GRAPHIQL",
|
||||
arg: "enableGraphiQL",
|
||||
},
|
||||
port: {
|
||||
doc: "The port to bind.",
|
||||
format: "port",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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",
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
declare module "farce" {
|
||||
// TODO: provide better typings.
|
||||
export class BrowserProtocol {}
|
||||
export class queryMiddleware {}
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
declare module "found-relay" {
|
||||
import { Environment } from "relay-runtime";
|
||||
export class Resolver {
|
||||
constructor(relayEnvironment: Environment);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user