html: use api to fetch auth token

This commit is contained in:
Shuanglei Tao
2020-02-06 17:24:00 +08:00
parent 463da8352e
commit 6bbe4db775
9 changed files with 8564 additions and 8350 deletions

View File

@@ -65,6 +65,7 @@
"decko": "^1.2.0",
"file-saver": "^2.0.2",
"preact": "^10.0.5",
"whatwg-fetch": "^3.0.0",
"xterm": "^4.4.0",
"xterm-addon-fit": "^0.3.0",
"xterm-addon-web-links": "^0.2.1",

View File

@@ -8,9 +8,10 @@ if ((module as any).hot) {
require('preact/debug');
}
const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://';
const wsPath = window.location.pathname.endsWith('/') ? 'ws' : '/ws';
const url = [protocol, window.location.host, window.location.pathname, wsPath, window.location.search].join('');
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const path = window.location.pathname.replace(/[\/]+$/, '');
const wsUrl = [protocol, '//', window.location.host, path, '/ws', window.location.search].join('');
const tokenUrl = [window.location.protocol, '//', window.location.host, path, '/token'].join('');
const termOptions = {
fontSize: 13,
fontFamily: 'Menlo For Powerline,Consolas,Liberation Mono,Menlo,Courier,monospace',
@@ -39,6 +40,6 @@ const termOptions = {
export class App extends Component {
render() {
return <Xterm id="terminal-container" url={url} options={termOptions} />;
return <Xterm id="terminal-container" wsUrl={wsUrl} tokenUrl={tokenUrl} options={termOptions} />;
}
}

View File

@@ -17,7 +17,6 @@ export interface TerminalExtended extends Terminal {
export interface WindowExtended extends Window {
term: TerminalExtended;
tty_auth_token?: string;
}
declare let window: WindowExtended;
@@ -34,7 +33,8 @@ const enum Command {
interface Props {
id: string;
url: string;
wsUrl: string;
tokenUrl: string;
options: ITerminalOptions;
}
@@ -47,6 +47,7 @@ export class Xterm extends Component<Props> {
private overlayAddon: OverlayAddon;
private zmodemAddon: ZmodemAddon;
private socket: WebSocket;
private token: string;
private title: string;
private resizeTimeout: number;
private backoff: backoff.Backoff;
@@ -65,7 +66,7 @@ export class Xterm extends Component<Props> {
});
this.backoff.on('ready', () => {
this.backoffLock = false;
this.openTerminal();
this.refreshToken().then(this.openTerminal);
});
this.backoff.on('backoff', (_, delay: number) => {
console.log(`[ttyd] will attempt to reconnect websocket in ${delay}ms`);
@@ -73,7 +74,8 @@ export class Xterm extends Component<Props> {
});
}
componentDidMount() {
async componentDidMount() {
await this.refreshToken();
this.openTerminal();
}
@@ -102,6 +104,19 @@ export class Xterm extends Component<Props> {
socket.send(payload);
}
@bind
private async refreshToken() {
try {
const resp = await fetch(this.props.tokenUrl);
if (resp.ok) {
const json = await resp.json();
this.token = json.token;
}
} catch (e) {
console.log(`[ttyd] fetch ${this.props.tokenUrl}: ${e.message}`);
}
}
@bind
private onWindowResize() {
const { fitAddon } = this;
@@ -121,7 +136,7 @@ export class Xterm extends Component<Props> {
this.terminal.dispose();
}
this.socket = new WebSocket(this.props.url, ['tty']);
this.socket = new WebSocket(this.props.wsUrl, ['tty']);
this.terminal = new Terminal(this.props.options);
const { socket, terminal, container, fitAddon, overlayAddon } = this;
window.term = terminal as TerminalExtended;
@@ -174,9 +189,7 @@ export class Xterm extends Component<Props> {
this.backoff.reset();
const { socket, textEncoder, fitAddon } = this;
const authToken = window.tty_auth_token;
socket.send(textEncoder.encode(JSON.stringify({ AuthToken: authToken })));
socket.send(textEncoder.encode(JSON.stringify({ AuthToken: this.token })));
fitAddon.fit();
}
@@ -188,11 +201,6 @@ export class Xterm extends Component<Props> {
overlayAddon.showOverlay('Connection Closed', null);
window.removeEventListener('beforeunload', this.onWindowUnload);
// 1008: POLICY_VIOLATION - Auth failure
if (event.code === 1008) {
window.location.reload();
}
// 1000: CLOSE_NORMAL
if (event.code !== 1000) {
this.reconnect();

View File

@@ -1,3 +1,4 @@
import 'whatwg-fetch';
import { h, render } from 'preact';
import { App } from './components/app';
import './style/index.scss';

View File

@@ -10,7 +10,6 @@
<% } %>
</head>
<body>
<script src="auth_token.js"></script>
<% for (const js in htmlWebpackPlugin.files.js) { %>
<script inline type="text/javascript" src="<%= htmlWebpackPlugin.files.js[js] %>"></script>
<% } %>

View File

@@ -73,7 +73,7 @@ const devConfig = {
compress: true,
port: 9000,
proxy: [{
context: ['/auth_token.js', '/ws'],
context: ['/token', '/ws'],
target: 'http://localhost:7681',
ws: true
}]

View File

@@ -8477,6 +8477,11 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
whatwg-fetch@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
which-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"

16853
src/html.h

File diff suppressed because it is too large Load Diff

View File

@@ -149,15 +149,15 @@ callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, voi
p = buffer + LWS_PRE;
end = p + sizeof(buffer) - LWS_PRE;
if (strncmp(pss->path, "/auth_token.js", 14) == 0) {
if (strncmp(pss->path, "/token", 6) == 0) {
const char *credential = server->credential != NULL ? server->credential : "";
size_t n = sprintf(buf, "var tty_auth_token = '%s';\n", credential);
size_t n = sprintf(buf, "{\"token\": \"%s\"}", credential);
if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
return 1;
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_HTTP_CONTENT_TYPE,
(unsigned char *) "application/javascript",
22, &p, end))
(unsigned char *) "application/json;charset=utf-8",
30, &p, end))
return 1;
if (lws_add_http_header_content_length(wsi, (unsigned long) n, &p, end))
return 1;