Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Modify components to support ionic fork
Browse files Browse the repository at this point in the history
justinr1234 committed Aug 18, 2020

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
1 parent 9d7016c commit 8ac7982
Showing 11 changed files with 202 additions and 115 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -4,3 +4,4 @@ node_modules
/data/schema.sql
/@app/graphql/index.*
/@app/client/.next
**/build
111 changes: 0 additions & 111 deletions @app/lib/src/withApollo.ts

This file was deleted.

131 changes: 131 additions & 0 deletions @app/lib/src/withApollo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { getDataFromTree } from "@apollo/react-ssr";
import { InMemoryCache, NormalizedCacheObject } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
import { ApolloLink, split } from "apollo-link";
import { onError } from "apollo-link-error";
import { HttpLink } from "apollo-link-http";
import { WebSocketLink } from "apollo-link-ws";
import { getOperationAST } from "graphql";
import withApolloBase, { InitApolloOptions } from "next-with-apollo";
import React from "react";
import { SubscriptionClient } from "subscriptions-transport-ws";
import ws from "ws";

import { GraphileApolloLink } from "./GraphileApolloLink";

interface WithApolloOptions {
useNext?: boolean;
rootUrl?: string;
}

let wsClient: SubscriptionClient | null = null;

export function resetWebsocketConnection(): void {
if (wsClient) {
wsClient.close(false, false);
}
}

function makeServerSideLink(req: any, res: any) {
return new GraphileApolloLink({
req,
res,
postgraphileMiddleware: req.app.get("postgraphileMiddleware"),
});
}

function makeClientSideLink(ROOT_URL: string) {
const nextDataEl =
typeof document !== "undefined" && document.getElementById("__NEXT_DATA__");
const headers = {};
if (nextDataEl && nextDataEl.textContent) {
const data = JSON.parse(nextDataEl.textContent);
headers["CSRF-Token"] = data.query.CSRF_TOKEN;
}
const httpLink = new HttpLink({
uri: `${ROOT_URL}/graphql`,
credentials:
process.env.NODE_ENV === "development" ? "include" : "same-origin",
headers,
});
wsClient = new SubscriptionClient(
`${ROOT_URL.replace(/^http/, "ws")}/graphql`,
{
reconnect: true,
},
typeof WebSocket !== "undefined" ? WebSocket : ws
);
const wsLink = new WebSocketLink(wsClient);

// Using the ability to split links, you can send data to each link
// depending on what kind of operation is being sent.
const mainLink = split(
// split based on operation type
({ query, operationName }) => {
const op = getOperationAST(query, operationName);
return (op && op.operation === "subscription") || false;
},
wsLink,
httpLink
);
return mainLink;
}

const getApolloClient = (
{ initialState, ctx }: InitApolloOptions<NormalizedCacheObject>,
withApolloOptions?: WithApolloOptions
): ApolloClient<NormalizedCacheObject> => {
const ROOT_URL = process.env.ROOT_URL || withApolloOptions?.rootUrl;
if (!ROOT_URL) {
throw new Error("ROOT_URL envvar is not set");
}

const onErrorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.error(
`[GraphQL error]: message: ${message}, location: ${JSON.stringify(
locations
)}, path: ${JSON.stringify(path)}`
)
);
if (networkError) console.error(`[Network error]: ${networkError}`);
});

const { req, res }: any = ctx || {};
const isServer = typeof window === "undefined";
const mainLink =
isServer && req && res
? makeServerSideLink(req, res)
: makeClientSideLink(ROOT_URL);

const client = new ApolloClient({
link: ApolloLink.from([onErrorLink, mainLink]),
cache: new InMemoryCache({
dataIdFromObject: (o) =>
o.__typename === "Query"
? "ROOT_QUERY"
: o.id
? `${o.__typename}:${o.id}`
: null,
}).restore(initialState || {}),
});

return client;
};

const withApolloWithNext = withApolloBase(getApolloClient, {
getDataFromTree,
});

const withApolloWithoutNext = (Component: any, options?: WithApolloOptions) => (
props: any
) => {
const apollo = getApolloClient({}, options);
return <Component {...props} apollo={apollo} />;
};

export const withApollo = (Component: any, options?: WithApolloOptions) =>
options?.useNext === false
? withApolloWithoutNext(Component, options)
: withApolloWithNext(Component);
2 changes: 2 additions & 0 deletions @app/server/package.json
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
"@graphile/pro": "^0.10.0",
"@types/connect-pg-simple": "^4.2.0",
"@types/connect-redis": "^0.0.13",
"@types/cors": "^2.8.7",
"@types/csurf": "^1.9.36",
"@types/express-session": "^1.17.0",
"@types/helmet": "^0.0.46",
@@ -30,6 +31,7 @@
"chalk": "^4.0.0",
"connect-pg-simple": "^6.1.0",
"connect-redis": "^4.0.4",
"cors": "^2.8.5",
"csurf": "^1.11.0",
"express": "^4.17.1",
"express-session": "^1.17.1",
1 change: 1 addition & 0 deletions @app/server/src/app.ts
Original file line number Diff line number Diff line change
@@ -99,6 +99,7 @@ export async function makeApp({
* express middleware. These helpers may be asynchronous, but they should
* operate very rapidly to enable quick as possible server startup.
*/
await middleware.installCors(app);
await middleware.installDatabasePools(app);
await middleware.installWorkerUtils(app);
await middleware.installHelmet(app);
2 changes: 2 additions & 0 deletions @app/server/src/middleware/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import installCors from "./installCors";
import installCSRFProtection from "./installCSRFProtection";
import installCypressServerCommand from "./installCypressServerCommand";
import installDatabasePools from "./installDatabasePools";
@@ -13,6 +14,7 @@ import installSSR from "./installSSR";
import installWorkerUtils from "./installWorkerUtils";

export {
installCors,
installCSRFProtection,
installDatabasePools,
installWorkerUtils,
21 changes: 21 additions & 0 deletions @app/server/src/middleware/installCSRFProtection.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import csrf from "csurf";
import { Express } from "express";
import url from "url";

const skipList = process.env.CSRF_SKIP_REFERERS
? process.env.CSRF_SKIP_REFERERS?.replace(/s\s/g, "")
.split(",")
.map((s) => {
// It is prefixed with a protocol
if (s.indexOf("//") !== -1) {
const { host: skipHost } = url.parse(s);
return skipHost;
}

return s;
})
: [];

export default (app: Express) => {
const csrfProtection = csrf({
@@ -21,6 +36,12 @@ export default (app: Express) => {
) {
// Bypass CSRF for GraphiQL
next();
} else if (
skipList &&
skipList.includes(url.parse(req.headers.referer || "").host)
) {
// Bypass CSRF for named referers
next();
} else {
csrfProtection(req, res, next);
}
19 changes: 19 additions & 0 deletions @app/server/src/middleware/installCors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import cors from "cors";
import { Express } from "express";

export default (app: Express) => {
const origin = [];
if (process.env.ROOT_URL) {
origin.push(process.env.ROOT_URL);
}
if (process.env.CORS_ALLOWED_URLS) {
origin.push(
...(process.env.CORS_ALLOWED_URLS?.replace(/s\s/g, "").split(",") || [])
);
}
const corsOptions = {
origin,
credentials: true,
};
app.use(cors(corsOptions));
};
8 changes: 7 additions & 1 deletion @app/server/src/middleware/installSession.ts
Original file line number Diff line number Diff line change
@@ -75,7 +75,13 @@ export default (app: Express) => {
* different authentication method such as bearer tokens.
*/
const wrappedSessionMiddleware: RequestHandler = (req, res, next) => {
if (req.isSameOrigin) {
const origins = [];
if (process.env.SESSION_ALLOWED_ORIGINS) {
origins.push(
...(process.env.SESSION_ALLOWED_ORIGINS?.replace(/s\s/g, "").split(",") || [])
);
}
if (req.isSameOrigin || origins.includes(req.get('Origin') || '')) {
sessionMiddleware(req, res, next);
} else {
next();
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
"private": true,
"description": "Description of project here",
"scripts": {
"setup": "yarn && node ./scripts/setup.js",
"setup": "yarn && node ./scripts/setup.js && lerna run setup",
"start": "node ./scripts/start.js",
"pretest": "lerna run pretest",
"test": "node scripts/test.js",
Loading

0 comments on commit 8ac7982

Please sign in to comment.