Skip to content

Commit

Permalink
Modify components to support ionic fork
Browse files Browse the repository at this point in the history
  • Loading branch information
justinr1234 committed Aug 13, 2020
1 parent 9d7016c commit 5c07533
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 114 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
1 change: 1 addition & 0 deletions @app/server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
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";
Expand All @@ -13,6 +14,7 @@ import installSSR from "./installSSR";
import installWorkerUtils from "./installWorkerUtils";

export {
installCors,
installCSRFProtection,
installDatabasePools,
installWorkerUtils,
Expand Down
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({
Expand All @@ -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);
}
Expand Down
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));
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
19 changes: 17 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2793,6 +2793,13 @@
"@types/keygrip" "*"
"@types/node" "*"

"@types/cors@^2.8.7":
version "2.8.7"
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.7.tgz#ab2f47f1cba93bce27dfd3639b006cc0e5600889"
integrity sha512-sOdDRU3oRS7LBNTIqwDkPJyq0lpHYcbMTt0TrjzsXbk/e37hcLTH6eZX7CdbDeN0yJJvzw9hFBZkbtCSbk/jAQ==
dependencies:
"@types/express" "*"

"@types/csurf@^1.9.36":
version "1.9.36"
resolved "https://registry.yarnpkg.com/@types/csurf/-/csurf-1.9.36.tgz#f0139ef24f4d2a1a59674e2fcd7a13d86cff626a"
Expand Down Expand Up @@ -5456,6 +5463,14 @@ core_d@^1.0.1:
dependencies:
supports-color "^5.5.0"

cors@^2.8.5:
version "2.8.5"
resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
dependencies:
object-assign "^4"
vary "^1"

[email protected], cosmiconfig@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982"
Expand Down Expand Up @@ -11399,7 +11414,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE=

[email protected], object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
[email protected], object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
Expand Down Expand Up @@ -15711,7 +15726,7 @@ validate-npm-package-name@^3.0.0:
dependencies:
builtins "^1.0.3"

vary@~1.1.2:
vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
Expand Down

0 comments on commit 5c07533

Please sign in to comment.