-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #238 from binbat/feat/web-live777-token-auth
feat(web): live777 token auth webui
- Loading branch information
Showing
9 changed files
with
170 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { useState } from 'preact/hooks'; | ||
import { TargetedEvent } from 'preact/compat'; | ||
|
||
import * as api from '../../shared/api'; | ||
import { alertError } from '../../shared/utils'; | ||
|
||
export interface LoginProps { | ||
onSuccess?: (token: string) => void; | ||
} | ||
|
||
export function Login({ onSuccess }: LoginProps) { | ||
const [token, setToken] = useState(''); | ||
|
||
const onTokenSubmit = async (e: TargetedEvent) => { | ||
e.preventDefault(); | ||
const tk = token.indexOf(' ') < 0 ? `Bearer ${token}` : token; | ||
api.setAuthToken(tk); | ||
try { | ||
await api.getStreams(); | ||
onSuccess?.(token); | ||
} catch (e) { | ||
api.setAuthToken(''); | ||
alertError(e); | ||
} | ||
}; | ||
|
||
return ( | ||
<fieldset> | ||
<legend>Authorization Required</legend> | ||
<form onSubmit={onTokenSubmit}> | ||
<span class="inline-block min-w-24 font-bold">Token</span> | ||
<input value={token} onInput={e => setToken(e.currentTarget?.value)} /> | ||
<br /> | ||
<input type="submit" value="Login" /> | ||
</form> | ||
</fieldset> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,30 @@ | ||
import { useState } from 'preact/hooks'; | ||
|
||
import * as api from '../shared/api'; | ||
import { Live777Logo } from '../shared/components/live777-logo'; | ||
import { StreamsTable } from '../shared/components/streams-table'; | ||
import { TokenContext } from '../shared/context'; | ||
import { useNeedAuthorization } from '../shared/hooks/use-need-authorization'; | ||
|
||
import { Login } from './components/login'; | ||
|
||
export function Liveion() { | ||
const [token, setToken] = useState(''); | ||
const [needsAuthorizaiton, setNeedsAuthorization] = useNeedAuthorization(api); | ||
|
||
const onLoginSuccess = (t: string) => { | ||
setToken(t); | ||
setNeedsAuthorization(false); | ||
}; | ||
|
||
return ( | ||
<> | ||
<TokenContext.Provider value={{ token }}> | ||
<Live777Logo /> | ||
<StreamsTable showCascade /> | ||
</> | ||
{needsAuthorizaiton ? ( | ||
<Login onSuccess={onLoginSuccess} /> | ||
) : ( | ||
<StreamsTable showCascade /> | ||
)} | ||
</TokenContext.Provider> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { ConfiguredMiddleware } from 'wretch'; | ||
|
||
const Authorization = 'Authorization'; | ||
|
||
export type UnauthorizedCallback = () => void; | ||
|
||
interface AuthorizationContext { | ||
token: string | null; | ||
callbacks: UnauthorizedCallback[]; | ||
} | ||
|
||
export interface AuthorizationCallbacks { | ||
setAuthorization: (token: string) => void; | ||
addUnauthorizedCallback: (cb: UnauthorizedCallback) => void; | ||
removeUnauthorizedCallback: (cb: UnauthorizedCallback) => boolean; | ||
} | ||
|
||
type AuthorizationMiddleware = ConfiguredMiddleware & AuthorizationCallbacks; | ||
|
||
export function makeAuthorizationMiddleware(): AuthorizationMiddleware { | ||
const ctx: AuthorizationContext = { | ||
token: null, | ||
callbacks: [] | ||
}; | ||
const middleware: AuthorizationMiddleware = (next) => async (url, opts) => { | ||
if (ctx.token) { | ||
if (typeof opts.headers !== 'object') { | ||
opts.headers = { [Authorization]: ctx.token }; | ||
} else { | ||
opts.headers[Authorization] = ctx.token; | ||
} | ||
} | ||
const res = await next(url, opts); | ||
if (res.status === 401) { | ||
ctx.callbacks.forEach(cb => cb()); | ||
} | ||
return res; | ||
}; | ||
middleware.setAuthorization = token => ctx.token = token; | ||
middleware.addUnauthorizedCallback = cb => ctx.callbacks.push(cb); | ||
middleware.removeUnauthorizedCallback = cb => { | ||
const i = ctx.callbacks.indexOf(cb); | ||
if (i >= 0) { | ||
ctx.callbacks.splice(i, 1); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
return middleware; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { useCallback, useEffect, useState } from 'preact/hooks'; | ||
|
||
import { type UnauthorizedCallback } from '../authorization-middleware'; | ||
|
||
interface AuthorizationCallbacks { | ||
addUnauthorizedCallback: (cb: UnauthorizedCallback) => void; | ||
removeUnauthorizedCallback: (cb: UnauthorizedCallback) => boolean; | ||
} | ||
|
||
export function useNeedAuthorization(auth: AuthorizationCallbacks) { | ||
const needsAuthorizaiton = useState(false); | ||
const unauthorizedCallback = useCallback(() => { | ||
needsAuthorizaiton[1](true); | ||
}, []); | ||
|
||
useEffect(() => { | ||
auth.addUnauthorizedCallback(unauthorizedCallback); | ||
return () => auth.removeUnauthorizedCallback(unauthorizedCallback); | ||
}, []); | ||
|
||
return needsAuthorizaiton; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters