Skip to content
This repository was archived by the owner on Mar 12, 2025. It is now read-only.

Commit 79579fa

Browse files
Merge pull request #8 from topcoder-platform/tc-auth
Fix issue where tc-accounts module, relevant for topcoder based authentication, was throwing errors during build
2 parents 4a6dc9f + 22f8259 commit 79579fa

File tree

12 files changed

+192
-20
lines changed

12 files changed

+192
-20
lines changed

config/default.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44
module.exports = {
55
LOG_LEVEL: process.env.LOG_LEVEL || 'debug',
6-
PORT: process.env.PORT || 4000,
6+
PORT: process.env.PORT || 3000,
77
// see https://www.npmjs.com/package/no-kafka for available options
88
KAFKA_OPTIONS: {
99
connectionString: process.env.KAFKA_URL || 'localhost:9092',

set-env.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ const targetPath = './ui/src/config/config.js';
44

55
const envConfigFile = `
66
const config = {
7-
API_URL: '${process.env.API_URL || 'http://localhost:4000'}/api/v1',
8-
WS_URL: '${process.env.WS_URL || 'ws://localhost:4000'}',
9-
DEFAULT_MESSAGE_COUNT: ${process.env.DEFAULT_MESSAGE_COUNT || 20}
7+
API_URL: '${process.env.API_URL || 'http://localhost:3000'}/api/v1',
8+
WS_URL: '${process.env.WS_URL || 'ws://localhost:3000'}',
9+
DEFAULT_MESSAGE_COUNT: ${process.env.DEFAULT_MESSAGE_COUNT} || 20,
10+
TC_AUTH_URL: '${process.env.TC_AUTH_URL || 'https://accounts.topcoder-dev.com'}',
11+
ACCOUNTS_APP_CONNECTOR: '${process.env.ACCOUNTS_APP_CONNECTOR || 'https://accounts.topcoder-dev.com/connector.html'}',
12+
APP_URL: '${process.env.APP_URL || 'http://localhost:3000'}',
1013
};
1114
1215
export default config;
16+
1317
`;
1418

1519
writeFile(targetPath, envConfigFile, (err) => {

ui/package-lock.json

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

ui/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
"react-dom": "^16.3.2",
1111
"react-router-dom": "^4.3.1",
1212
"react-scripts": "1.1.4",
13-
"superagent": "^3.8.3",
14-
"tc-accounts": "git+https://github.com/appirio-tech/accounts-app.git#dev"
13+
"superagent": "^3.8.3"
1514
},
1615
"scripts": {
1716
"start": "react-scripts start",

ui/src/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { Component } from 'react';
22
import { BrowserRouter as Router } from 'react-router-dom';
3-
import { getFreshToken, configureConnector, decodeToken } from 'tc-accounts';
3+
import { getFreshToken, configureConnector, decodeToken } from './services/tc-auth';
44
import loadingImg from './loading.gif';
55
import './App.css';
66
import DayPickerInput from 'react-day-picker/DayPickerInput';

ui/src/config/config.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11

22
const config = {
3-
API_URL: 'http://localhost:4000/api/v1',
4-
WS_URL: 'ws://localhost:4000',
5-
DEFAULT_MESSAGE_COUNT: 20,
6-
TC_AUTH_URL: 'https://accounts.topcoder-dev.com',
7-
ACCOUNTS_APP_CONNECTOR: 'https://accounts.topcoder-dev.com/connector.html',
8-
APP_URL: 'http://local.topcoder-dev.com:3000',
3+
API_URL: undefined || 'http://localhost:3000/api/v1',
4+
WS_URL: undefined || 'ws://localhost:3000',
5+
DEFAULT_MESSAGE_COUNT: undefined || 20,
6+
TC_AUTH_URL: undefined || 'https://accounts.topcoder-dev.com',
7+
ACCOUNTS_APP_CONNECTOR: undefined || 'https://accounts.topcoder-dev.com/connector.html',
8+
APP_URL: undefined || 'http://localhost:3000',
99
};
1010

1111
export default config;
12+

ui/src/services/tc-auth/README

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
This folder contains a sub set of the changes located in https://github.com/appirio-tech/accounts-app
2+
3+
Create React script is unable to minify that module.
4+
5+
Hence, we are extracting into this folder only what is necessary for this app to function
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import {
2+
GET_FRESH_TOKEN_REQUEST,
3+
GET_FRESH_TOKEN_SUCCESS,
4+
GET_FRESH_TOKEN_FAILURE,
5+
LOGOUT_REQUEST,
6+
LOGOUT_SUCCESS,
7+
LOGOUT_FAILURE,
8+
} from './constants.js';
9+
import createFrame from './iframe.js';
10+
11+
let iframe = null;
12+
let loading = null;
13+
let url = '';
14+
let mock = false;
15+
let token = '';
16+
17+
export function configureConnector({ connectorUrl, frameId, mockMode, mockToken }) {
18+
if (mockMode) {
19+
mock = true;
20+
token = mockToken;
21+
} else if (iframe) {
22+
console.warn('tc-accounts connector can only be configured once, this request has been ignored.');
23+
} else {
24+
iframe = createFrame(frameId, connectorUrl);
25+
url = connectorUrl;
26+
27+
loading = new Promise((resolve) => {
28+
iframe.onload = function () {
29+
loading = null;
30+
resolve();
31+
};
32+
});
33+
}
34+
}
35+
36+
const proxyCall = function (REQUEST, SUCCESS, FAILURE, params = {}) {
37+
if (mock) {
38+
throw new Error('connector is running in mock mode. This method (proxyCall) should not be invoked.');
39+
}
40+
41+
if (!iframe) {
42+
throw new Error('connector has not yet been configured.');
43+
}
44+
45+
function request() {
46+
return new Promise((resolve, reject) => {
47+
function receiveMessage(e) {
48+
const safeFormat = e.data.type === SUCCESS || e.data.type === FAILURE;
49+
if (safeFormat) {
50+
window.removeEventListener('message', receiveMessage);
51+
if (e.data.type === SUCCESS) resolve(e.data);
52+
if (e.data.type === FAILURE) reject(e.error);
53+
}
54+
}
55+
56+
window.addEventListener('message', receiveMessage);
57+
58+
const payload = Object.assign({}, { type: REQUEST }, params);
59+
60+
iframe.contentWindow.postMessage(payload, url);
61+
});
62+
}
63+
64+
if (loading) {
65+
loading = loading.then(request);
66+
return loading;
67+
}
68+
69+
return request();
70+
};
71+
72+
export function getFreshToken() {
73+
if (mock) {
74+
if (token) {
75+
return Promise.resolve(token);
76+
}
77+
return Promise.reject('connector is running in mock mode, but no token has been specified.');
78+
}
79+
80+
return proxyCall(GET_FRESH_TOKEN_REQUEST, GET_FRESH_TOKEN_SUCCESS, GET_FRESH_TOKEN_FAILURE)
81+
.then(data => data.token);
82+
}
83+
84+
export function logout() {
85+
return proxyCall(LOGOUT_REQUEST, LOGOUT_SUCCESS, LOGOUT_FAILURE);
86+
}

ui/src/services/tc-auth/constants.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const GET_FRESH_TOKEN_REQUEST = 'GET_FRESH_TOKEN_REQUEST';
2+
export const GET_FRESH_TOKEN_SUCCESS = 'GET_FRESH_TOKEN_SUCCESS';
3+
export const GET_FRESH_TOKEN_FAILURE = 'GET_FRESH_TOKEN_FAILURE';
4+
5+
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST';
6+
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
7+
export const LOGOUT_FAILURE = 'LOGOUT_FAILURE';

ui/src/services/tc-auth/iframe.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default function createFrame(id, src) {
2+
const iframe = document.createElement('iframe');
3+
4+
iframe.id = id;
5+
iframe.src = src;
6+
iframe.width = 0;
7+
iframe.height = 0;
8+
iframe.frameborder = 0;
9+
10+
document.body.appendChild(iframe);
11+
12+
return iframe;
13+
}

ui/src/services/tc-auth/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export {
2+
configureConnector,
3+
getFreshToken,
4+
logout,
5+
} from './connector-wrapper';
6+
7+
export { decodeToken } from './token';

ui/src/services/tc-auth/token.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
function urlBase64Decode(str) {
2+
let output = str.replace(/-/g, '+').replace(/_/g, '/');
3+
4+
switch (output.length % 4) {
5+
case 0:
6+
break;
7+
8+
case 2:
9+
output += '==';
10+
break;
11+
12+
case 3:
13+
output += '=';
14+
break;
15+
16+
default:
17+
throw new Error('Illegal base64url string!');
18+
}
19+
return decodeURIComponent(escape(atob(output)));
20+
}
21+
22+
export function decodeToken(token) {
23+
const parts = token.split('.');
24+
25+
if (parts.length !== 3) {
26+
throw new Error('The token is invalid');
27+
}
28+
29+
const decoded = urlBase64Decode(parts[1]);
30+
31+
if (!decoded) {
32+
throw new Error('Cannot decode the token');
33+
}
34+
35+
return JSON.parse(decoded);
36+
}

0 commit comments

Comments
 (0)