Skip to content

Commit 9f39fc0

Browse files
authored
Merge pull request #246 from oslabs-beta/master
Merging our oslabs-beta master to open-source-labs dev
2 parents efbf336 + 7fe767b commit 9f39fc0

23 files changed

+635
-226
lines changed

.babelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
"presets": [
88
"@babel/preset-env",
99
"@babel/preset-react"
10-
]
10+
],
1111
}

main.js

Lines changed: 137 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,26 @@ process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
77
const { app, BrowserWindow, TouchBar, ipcMain } = require('electron');
88
const path = require('path');
99
const url = require('url');
10-
// This allows electron to spin up this server to localhost:7000 when the app starts up
11-
require('./httpserver');
10+
1211
// Import Auto-Updater- Swell will update itself
1312
const { autoUpdater } = require('electron-updater');
1413
const log = require('electron-log');
1514
// TouchBarButtons are our nav buttons(ex: Select All, Deselect All, Open Selected, Close Selected, Clear All)
1615
const { TouchBarButton, TouchBarSpacer } = TouchBar;
1716

17+
// basic http cookie parser
18+
const cookie = require('cookie');
19+
// node-fetch for the fetch request
20+
const fetch2 = require('node-fetch');
21+
22+
// GraphQL imports
23+
const ApolloClient = require('apollo-client').ApolloClient;
24+
const gql = require('graphql-tag');
25+
const { InMemoryCache } = require('apollo-cache-inmemory');
26+
const { createHttpLink } = require('apollo-link-http');
27+
const { ApolloLink } = require('apollo-link');
28+
const { onError } = require("apollo-link-error");
29+
1830
// configure logging
1931
autoUpdater.logger = log;
2032
autoUpdater.logger.transports.file.level = 'info';
@@ -126,7 +138,7 @@ function createWindow() {
126138
webPreferences: {
127139
"nodeIntegration": true,
128140
"sandbox": false,
129-
webSecurity: false,
141+
webSecurity: true,
130142
},
131143
icon: `${__dirname}/src/assets/icons/64x64.png`
132144
})
@@ -263,3 +275,125 @@ app.on('activate', () => {
263275
createWindow();
264276
}
265277
});
278+
279+
280+
// ipcMain listener that
281+
ipcMain.on('http1-fetch-message', (event, arg) => {
282+
const { method, headers, body } = arg.options;
283+
284+
fetch2(headers.url, { method, headers, body })
285+
.then((response) => {
286+
const headers = response.headers.raw();
287+
// check if the endpoint sends SSE
288+
// add status code for regular http requests in the response header
289+
290+
if (headers['content-type'][0].includes('stream')) {
291+
// invoke another func that fetches to SSE and reads stream
292+
// params: method, headers, body
293+
event.sender.send('http1-fetch-reply', { headers, body: { error: 'This Is An SSE endpoint' } })
294+
}
295+
else {
296+
headers[':status'] = response.status;
297+
298+
const receivedCookie = headers['set-cookie'];
299+
headers.cookies = receivedCookie;
300+
301+
const contents = /json/.test(response.headers.get('content-type')) ? response.json() : response.text();
302+
contents
303+
.then(body => {
304+
event.sender.send('http1-fetch-reply', { headers, body })
305+
})
306+
.catch(error => console.log('ERROR', error))
307+
}
308+
})
309+
.catch(error => console.log(error))
310+
})
311+
312+
ipcMain.on('open-gql', (event, args) => {
313+
const reqResObj = args.reqResObj;
314+
315+
// populating headers object with response headers - except for Content-Type
316+
const headers = {};
317+
reqResObj.request.headers.filter(item => item.key !== 'Content-Type').forEach((item) => {
318+
headers[item.key] = item.value;
319+
});
320+
321+
// request cookies from reqResObj to request headers
322+
let cookies;
323+
if (reqResObj.request.cookies.length) {
324+
cookies = reqResObj.request.cookies.reduce((acc,userCookie) => {
325+
return acc + `${userCookie.key}=${userCookie.value}; `;
326+
}, "")
327+
}
328+
headers.Cookie = cookies;
329+
330+
// afterware takes headers from context response object, copies to reqResObj
331+
const afterLink = new ApolloLink((operation, forward) => {
332+
return forward(operation).map(response => {
333+
const context = operation.getContext();
334+
const headers = context.response.headers.entries();
335+
for (let headerItem of headers) {
336+
const key = headerItem[0].split('-').map(item => item[0].toUpperCase() + item.slice(1)).join('-');
337+
reqResObj.response.headers[key] = headerItem[1];
338+
339+
// if cookies were sent by server, parse first key-value pair, then cookie.parse the rest
340+
if (headerItem[0] === 'set-cookie'){
341+
const parsedCookies = [];
342+
const cookieStrArr = headerItem[1].split(', ');
343+
cookieStrArr.forEach(thisCookie => {
344+
thisCookie = thisCookie.toLowerCase();
345+
// index of first semicolon
346+
const idx = thisCookie.search(/[;]/g);
347+
// first key value pair
348+
const keyValueArr = thisCookie.slice(0, idx).split('=');
349+
// cookie contents after first key value pair
350+
const parsedRemainingCookieProperties = cookie.parse(thisCookie.slice(idx + 1));
351+
352+
const parsedCookie = {...parsedRemainingCookieProperties, name: keyValueArr[0], value: keyValueArr[1]};
353+
354+
parsedCookies.push(parsedCookie);
355+
})
356+
reqResObj.response.cookies = parsedCookies;
357+
}
358+
}
359+
360+
return response;
361+
});
362+
});
363+
364+
// creates http connection to host
365+
const httpLink = createHttpLink({ uri: reqResObj.url, headers, credentials: 'include', fetch: fetch2, });
366+
367+
// additive composition of multiple links
368+
const link = ApolloLink.from([
369+
afterLink,
370+
httpLink
371+
]);
372+
373+
const client = new ApolloClient({
374+
link,
375+
cache: new InMemoryCache(),
376+
});
377+
378+
const body = gql`${reqResObj.request.body}`;
379+
const variables = reqResObj.request.bodyVariables ? JSON.parse(reqResObj.request.bodyVariables) : {};
380+
381+
if (reqResObj.request.method === 'QUERY') {
382+
client.query({ query: body, variables })
383+
384+
.then(data => {
385+
event.sender.send('reply-gql', {reqResObj, data})})
386+
.catch((err) => {
387+
console.error(err);
388+
event.sender.send('reply-gql', {error: err.networkError, reqResObj});
389+
});
390+
}
391+
else if (reqResObj.request.method === 'MUTATION') {
392+
client.mutate({ mutation: body, variables })
393+
.then(data => event.sender.send('reply-gql', {reqResObj, data}))
394+
.catch((err) => {
395+
console.error(err);
396+
});
397+
}
398+
});
399+

package-lock.json

Lines changed: 64 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,10 @@
130130
"dependencies": {
131131
"apollo-cache-inmemory": "^1.6.2",
132132
"apollo-client": "^2.6.3",
133+
"apollo-link": "^1.2.13",
134+
"apollo-link-error": "^1.1.12",
133135
"apollo-link-http": "^1.5.15",
134-
"apollo-link-ws": "^1.0.18",
136+
"apollo-link-ws": "^1.0.19",
135137
"chart.js": "^2.7.3",
136138
"classnames": "^2.2.6",
137139
"date-fns": "^1.29.0",
@@ -144,6 +146,7 @@
144146
"graphql": "^14.4.2",
145147
"graphql-tag": "^2.10.1",
146148
"isomorphic-fetch": "^2.2.1",
149+
"node-fetch": "^2.6.0",
147150
"node-sass": "^4.10.0",
148151
"nodemon": "^1.19.1",
149152
"path": "^0.12.7",
@@ -159,6 +162,7 @@
159162
"react-syntax-highlighter-virtualized-renderer": "^1.1.0",
160163
"redux": "^3.7.2",
161164
"rpmbuild": "0.0.22",
165+
"set-cookie-parser": "^2.4.0",
162166
"status-indicator": "^1.0.9",
163167
"subscriptions-transport-ws": "^0.9.16",
164168
"uuid": "^3.3.2",
@@ -201,4 +205,4 @@
201205
"webpack-cli": "^3.1.2",
202206
"webpack-dev-server": "^3.1.14"
203207
}
204-
}
208+
}

src/assets/style/grid.scss

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,36 @@
7979
}
8080
}
8181
}
82+
.grid-7 {
83+
background: white;
84+
border: 1px solid $bordergray;
85+
border-bottom: 0;
86+
display: grid;
87+
grid-template-columns: 10% 12% 12% 6% 20% 20% 20%;
88+
height: auto;
89+
width: 100%;
90+
div {
91+
border-right: 1px solid $bordergray;
92+
padding: 0 15px;
93+
position: relative;
94+
&:first-child {
95+
max-height: 30px;
96+
}
97+
&:nth-child(-n+2) {
98+
padding: 0;
99+
}
100+
&:nth-child(-n+3) {
101+
padding: 0;
102+
}
103+
&:nth-child(4) {
104+
max-height: 30px;
105+
padding: 5px 11px;
106+
}
107+
&:last-child {
108+
border-right: none;
109+
}
110+
}
111+
}
82112
.grid-9 {
83113
background: white;
84114
border: 1px solid $bordergray;

src/client/actions/actionTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const SET_NEW_REQUEST_FIELDS = "SET_NEW_REQUEST_FIELDS";
1818
export const SET_NEW_REQUEST_HEADERS = "SET_NEW_REQUEST_HEADERS";
1919
export const SET_NEW_REQUEST_BODY = "SET_NEW_REQUEST_BODY";
2020
export const SET_NEW_REQUEST_COOKIES = "SET_NEW_REQUEST_COOKIES";
21+
export const SET_NEW_REQUEST_SSE = "SET_NEW_REQUEST_SSE";
2122

2223
export const SET_CURRENT_TAB = "SET_CURRENT_TAB";
2324

src/client/actions/actions.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ export const setNewRequestCookies = (cookies) => ({
7676
payload : cookies
7777
});
7878

79+
export const setNewRequestSSE = (SSEBool) => ({
80+
type: types.SET_NEW_REQUEST_SSE,
81+
payload : SSEBool
82+
});
83+
7984
export const setCurrentTab = (tab) => ({
8085
type: types.SET_CURRENT_TAB,
8186
payload: tab,

0 commit comments

Comments
 (0)