mirror of
https://github.com/tsl0922/ttyd.git
synced 2025-12-22 03:44:19 +01:00
html: use api to fetch auth token
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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} />;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'whatwg-fetch';
|
||||
import { h, render } from 'preact';
|
||||
import { App } from './components/app';
|
||||
import './style/index.scss';
|
||||
|
||||
@@ -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>
|
||||
<% } %>
|
||||
|
||||
@@ -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
|
||||
}]
|
||||
|
||||
@@ -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
16853
src/html.h
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user