Skip to content

Commit 42e01a7

Browse files
committed
Modify components to support ionic fork
1 parent 9d7016c commit 42e01a7

File tree

8 files changed

+193
-113
lines changed

8 files changed

+193
-113
lines changed

@app/lib/src/withApollo.ts

Lines changed: 0 additions & 111 deletions
This file was deleted.

@app/lib/src/withApollo.tsx

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { getDataFromTree } from "@apollo/react-ssr";
2+
import { InMemoryCache, NormalizedCacheObject } from "apollo-cache-inmemory";
3+
import { ApolloClient } from "apollo-client";
4+
import { ApolloLink, split } from "apollo-link";
5+
import { onError } from "apollo-link-error";
6+
import { HttpLink } from "apollo-link-http";
7+
import { WebSocketLink } from "apollo-link-ws";
8+
import { getOperationAST } from "graphql";
9+
import withApolloBase, { InitApolloOptions } from "next-with-apollo";
10+
import React from "react";
11+
import { SubscriptionClient } from "subscriptions-transport-ws";
12+
import ws from "ws";
13+
14+
import { GraphileApolloLink } from "./GraphileApolloLink";
15+
16+
interface WithApolloOptions {
17+
useNext?: boolean;
18+
rootUrl?: string;
19+
}
20+
21+
let wsClient: SubscriptionClient | null = null;
22+
23+
export function resetWebsocketConnection(): void {
24+
if (wsClient) {
25+
wsClient.close(false, false);
26+
}
27+
}
28+
29+
function makeServerSideLink(req: any, res: any) {
30+
return new GraphileApolloLink({
31+
req,
32+
res,
33+
postgraphileMiddleware: req.app.get("postgraphileMiddleware"),
34+
});
35+
}
36+
37+
function makeClientSideLink(ROOT_URL: string) {
38+
const nextDataEl =
39+
typeof document !== "undefined" && document.getElementById("__NEXT_DATA__");
40+
const headers = {};
41+
if (nextDataEl && nextDataEl.textContent) {
42+
const data = JSON.parse(nextDataEl.textContent);
43+
headers["CSRF-Token"] = data.query.CSRF_TOKEN;
44+
}
45+
const httpLink = new HttpLink({
46+
uri: `${ROOT_URL}/graphql`,
47+
credentials:
48+
process.env.NODE_ENV === "development" ? "include" : "same-origin",
49+
headers,
50+
});
51+
wsClient = new SubscriptionClient(
52+
`${ROOT_URL.replace(/^http/, "ws")}/graphql`,
53+
{
54+
reconnect: true,
55+
},
56+
typeof WebSocket !== "undefined" ? WebSocket : ws
57+
);
58+
const wsLink = new WebSocketLink(wsClient);
59+
60+
// Using the ability to split links, you can send data to each link
61+
// depending on what kind of operation is being sent.
62+
const mainLink = split(
63+
// split based on operation type
64+
({ query, operationName }) => {
65+
const op = getOperationAST(query, operationName);
66+
return (op && op.operation === "subscription") || false;
67+
},
68+
wsLink,
69+
httpLink
70+
);
71+
return mainLink;
72+
}
73+
74+
const getApolloClient = (
75+
{ initialState, ctx }: InitApolloOptions<NormalizedCacheObject>,
76+
withApolloOptions?: WithApolloOptions
77+
): ApolloClient<NormalizedCacheObject> => {
78+
const ROOT_URL = process.env.ROOT_URL || withApolloOptions?.rootUrl;
79+
if (!ROOT_URL) {
80+
throw new Error("ROOT_URL envvar is not set");
81+
}
82+
83+
const onErrorLink = onError(({ graphQLErrors, networkError }) => {
84+
if (graphQLErrors)
85+
graphQLErrors.map(({ message, locations, path }) =>
86+
console.error(
87+
`[GraphQL error]: message: ${message}, location: ${JSON.stringify(
88+
locations
89+
)}, path: ${JSON.stringify(path)}`
90+
)
91+
);
92+
if (networkError) console.error(`[Network error]: ${networkError}`);
93+
});
94+
95+
const { req, res }: any = ctx || {};
96+
const isServer = typeof window === "undefined";
97+
const mainLink =
98+
isServer && req && res
99+
? makeServerSideLink(req, res)
100+
: makeClientSideLink(ROOT_URL);
101+
102+
const client = new ApolloClient({
103+
link: ApolloLink.from([onErrorLink, mainLink]),
104+
cache: new InMemoryCache({
105+
dataIdFromObject: (o) =>
106+
o.__typename === "Query"
107+
? "ROOT_QUERY"
108+
: o.id
109+
? `${o.__typename}:${o.id}`
110+
: null,
111+
}).restore(initialState || {}),
112+
});
113+
114+
return client;
115+
};
116+
117+
const withApolloWithNext = withApolloBase(getApolloClient, {
118+
getDataFromTree,
119+
});
120+
121+
const withApolloWithoutNext = (Component: any, options?: WithApolloOptions) => (
122+
props: any
123+
) => {
124+
const apollo = getApolloClient({}, options);
125+
return <Component {...props} apollo={apollo} />;
126+
};
127+
128+
export const withApollo = (Component: any, options?: WithApolloOptions) =>
129+
options?.useNext === false
130+
? withApolloWithoutNext(Component, options)
131+
: withApolloWithNext(Component);

@app/server/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@graphile/pro": "^0.10.0",
1919
"@types/connect-pg-simple": "^4.2.0",
2020
"@types/connect-redis": "^0.0.13",
21+
"@types/cors": "^2.8.7",
2122
"@types/csurf": "^1.9.36",
2223
"@types/express-session": "^1.17.0",
2324
"@types/helmet": "^0.0.46",
@@ -30,6 +31,7 @@
3031
"chalk": "^4.0.0",
3132
"connect-pg-simple": "^6.1.0",
3233
"connect-redis": "^4.0.4",
34+
"cors": "^2.8.5",
3335
"csurf": "^1.11.0",
3436
"express": "^4.17.1",
3537
"express-session": "^1.17.1",

@app/server/src/app.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export async function makeApp({
9999
* express middleware. These helpers may be asynchronous, but they should
100100
* operate very rapidly to enable quick as possible server startup.
101101
*/
102+
await middleware.installCors(app);
102103
await middleware.installDatabasePools(app);
103104
await middleware.installWorkerUtils(app);
104105
await middleware.installHelmet(app);

@app/server/src/middleware/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import installCors from "./installCors";
12
import installCSRFProtection from "./installCSRFProtection";
23
import installCypressServerCommand from "./installCypressServerCommand";
34
import installDatabasePools from "./installDatabasePools";
@@ -13,6 +14,7 @@ import installSSR from "./installSSR";
1314
import installWorkerUtils from "./installWorkerUtils";
1415

1516
export {
17+
installCors,
1618
installCSRFProtection,
1719
installDatabasePools,
1820
installWorkerUtils,

@app/server/src/middleware/installCSRFProtection.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
import csrf from "csurf";
22
import { Express } from "express";
3+
import url from "url";
4+
5+
const skipList = process.env.CSRF_SKIP_REFERERS
6+
? process.env.CSRF_SKIP_REFERERS?.replace(/s\s/g, "")
7+
.split(",")
8+
.map((s) => {
9+
// It is prefixed with a protocol
10+
if (s.indexOf("//") !== -1) {
11+
const { host: skipHost } = url.parse(s);
12+
return skipHost;
13+
}
14+
15+
return s;
16+
})
17+
: [];
318

419
export default (app: Express) => {
520
const csrfProtection = csrf({
@@ -21,6 +36,12 @@ export default (app: Express) => {
2136
) {
2237
// Bypass CSRF for GraphiQL
2338
next();
39+
} else if (
40+
skipList &&
41+
skipList.includes(url.parse(req.headers.referer || "").host)
42+
) {
43+
// Bypass CSRF for named referers
44+
next();
2445
} else {
2546
csrfProtection(req, res, next);
2647
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import cors from "cors";
2+
import { Express } from "express";
3+
4+
export default (app: Express) => {
5+
const origin = [];
6+
if (process.env.ROOT_URL) {
7+
origin.push(process.env.ROOT_URL);
8+
}
9+
if (process.env.CORS_ALLOWED_URLS) {
10+
origin.push(
11+
...(process.env.CORS_ALLOWED_URLS?.replace(/s\s/g, "").split(",") || [])
12+
);
13+
}
14+
const corsOptions = {
15+
origin,
16+
credentials: true,
17+
};
18+
app.use(cors(corsOptions));
19+
};

yarn.lock

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,6 +2793,13 @@
27932793
"@types/keygrip" "*"
27942794
"@types/node" "*"
27952795

2796+
"@types/cors@^2.8.7":
2797+
version "2.8.7"
2798+
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.7.tgz#ab2f47f1cba93bce27dfd3639b006cc0e5600889"
2799+
integrity sha512-sOdDRU3oRS7LBNTIqwDkPJyq0lpHYcbMTt0TrjzsXbk/e37hcLTH6eZX7CdbDeN0yJJvzw9hFBZkbtCSbk/jAQ==
2800+
dependencies:
2801+
"@types/express" "*"
2802+
27962803
"@types/csurf@^1.9.36":
27972804
version "1.9.36"
27982805
resolved "https://registry.yarnpkg.com/@types/csurf/-/csurf-1.9.36.tgz#f0139ef24f4d2a1a59674e2fcd7a13d86cff626a"
@@ -5456,6 +5463,14 @@ core_d@^1.0.1:
54565463
dependencies:
54575464
supports-color "^5.5.0"
54585465

5466+
cors@^2.8.5:
5467+
version "2.8.5"
5468+
resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
5469+
integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
5470+
dependencies:
5471+
object-assign "^4"
5472+
vary "^1"
5473+
54595474
[email protected], cosmiconfig@^6.0.0:
54605475
version "6.0.0"
54615476
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982"
@@ -11399,7 +11414,7 @@ [email protected]:
1139911414
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
1140011415
integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE=
1140111416

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

15714-
vary@~1.1.2:
15729+
vary@^1, vary@~1.1.2:
1571515730
version "1.1.2"
1571615731
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
1571715732
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=

0 commit comments

Comments
 (0)