mirror of
https://github.com/warp-tech/warpgate.git
synced 2024-09-20 06:46:17 +08:00
lint
This commit is contained in:
parent
2c6dbd01ac
commit
4c8146273b
|
@ -146,7 +146,7 @@ impl DetailApi {
|
|||
return Ok(UpdateRoleResponse::NotFound);
|
||||
};
|
||||
|
||||
if &role.name == BUILTIN_ADMIN_ROLE_NAME {
|
||||
if role.name == BUILTIN_ADMIN_ROLE_NAME {
|
||||
return Ok(UpdateRoleResponse::Forbidden);
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ impl DetailApi {
|
|||
return Ok(DeleteRoleResponse::NotFound);
|
||||
};
|
||||
|
||||
if &role.name == BUILTIN_ADMIN_ROLE_NAME {
|
||||
if role.name == BUILTIN_ADMIN_ROLE_NAME {
|
||||
return Ok(DeleteRoleResponse::Forbidden);
|
||||
}
|
||||
|
||||
|
|
|
@ -281,8 +281,8 @@ impl RolesApi {
|
|||
let db = db.lock().await;
|
||||
|
||||
if !TargetRoleAssignment::Entity::find()
|
||||
.filter(TargetRoleAssignment::Column::TargetId.eq(id.0.clone()))
|
||||
.filter(TargetRoleAssignment::Column::RoleId.eq(role_id.0.clone()))
|
||||
.filter(TargetRoleAssignment::Column::TargetId.eq(id.0))
|
||||
.filter(TargetRoleAssignment::Column::RoleId.eq(role_id.0))
|
||||
.all(&*db)
|
||||
.await
|
||||
.map_err(WarpgateError::from)?
|
||||
|
@ -329,7 +329,7 @@ impl RolesApi {
|
|||
return Ok(DeleteTargetRoleResponse::NotFound);
|
||||
};
|
||||
|
||||
if &role.name == BUILTIN_ADMIN_ROLE_NAME && target.kind == TargetKind::WebAdmin {
|
||||
if role.name == BUILTIN_ADMIN_ROLE_NAME && target.kind == TargetKind::WebAdmin {
|
||||
return Ok(DeleteTargetRoleResponse::Forbidden);
|
||||
}
|
||||
|
||||
|
|
|
@ -262,8 +262,8 @@ impl RolesApi {
|
|||
let db = db.lock().await;
|
||||
|
||||
if !UserRoleAssignment::Entity::find()
|
||||
.filter(UserRoleAssignment::Column::UserId.eq(id.0.clone()))
|
||||
.filter(UserRoleAssignment::Column::RoleId.eq(role_id.0.clone()))
|
||||
.filter(UserRoleAssignment::Column::UserId.eq(id.0))
|
||||
.filter(UserRoleAssignment::Column::RoleId.eq(role_id.0))
|
||||
.all(&*db)
|
||||
.await
|
||||
.map_err(WarpgateError::from)?
|
||||
|
|
|
@ -23,6 +23,8 @@ pub enum WarpgateError {
|
|||
ExternalHostNotSet,
|
||||
#[error("URL contains no host")]
|
||||
NoHostInUrl,
|
||||
#[error("Inconsistent state error")]
|
||||
InconsistentState,
|
||||
}
|
||||
|
||||
impl ResponseError for WarpgateError {
|
||||
|
|
|
@ -229,7 +229,7 @@ impl Api {
|
|||
auth: Option<Data<&SessionAuthorization>>,
|
||||
id: Path<Uuid>,
|
||||
) -> poem::Result<AuthStateResponse> {
|
||||
let Some(state_arc) = get_auth_state(&*id, *services, auth.map(|x|x.0)).await else {
|
||||
let Some(state_arc) = get_auth_state(&id, &services, auth.map(|x|x.0)).await else {
|
||||
return Ok(AuthStateResponse::NotFound);
|
||||
};
|
||||
serialize_auth_state_inner(state_arc).await
|
||||
|
@ -247,7 +247,7 @@ impl Api {
|
|||
auth: Option<Data<&SessionAuthorization>>,
|
||||
id: Path<Uuid>,
|
||||
) -> poem::Result<AuthStateResponse> {
|
||||
let Some(state_arc) = get_auth_state(&*id, *services, auth.map(|x|x.0)).await else {
|
||||
let Some(state_arc) = get_auth_state(&id, &services, auth.map(|x|x.0)).await else {
|
||||
return Ok(AuthStateResponse::NotFound);
|
||||
};
|
||||
|
||||
|
@ -258,7 +258,7 @@ impl Api {
|
|||
};
|
||||
|
||||
if let AuthResult::Accepted { .. } = auth_result {
|
||||
services.auth_state_store.lock().await.complete(&*id).await;
|
||||
services.auth_state_store.lock().await.complete(&id).await;
|
||||
}
|
||||
serialize_auth_state_inner(state_arc).await
|
||||
}
|
||||
|
@ -275,11 +275,11 @@ impl Api {
|
|||
auth: Option<Data<&SessionAuthorization>>,
|
||||
id: Path<Uuid>,
|
||||
) -> poem::Result<AuthStateResponse> {
|
||||
let Some(state_arc) = get_auth_state(&*id, *services, auth.map(|x|x.0)).await else {
|
||||
let Some(state_arc) = get_auth_state(&id, &services, auth.map(|x|x.0)).await else {
|
||||
return Ok(AuthStateResponse::NotFound);
|
||||
};
|
||||
state_arc.lock().await.reject();
|
||||
services.auth_state_store.lock().await.complete(&*id).await;
|
||||
services.auth_state_store.lock().await.complete(&id).await;
|
||||
serialize_auth_state_inner(state_arc).await
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ async fn get_auth_state(
|
|||
return None;
|
||||
};
|
||||
|
||||
let Some(state_arc) = store.get(&*id) else {
|
||||
let Some(state_arc) = store.get(&id) else {
|
||||
return None;
|
||||
};
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ impl Api {
|
|||
services: Data<&Services>,
|
||||
) -> poem::Result<GetSsoProvidersResponse> {
|
||||
let mut providers = services.config.lock().await.store.sso_providers.clone();
|
||||
providers.sort_by(|a, b| a.label().cmp(&b.label()));
|
||||
providers.sort_by(|a, b| a.label().cmp(b.label()));
|
||||
Ok(GetSsoProvidersResponse::Ok(Json(
|
||||
providers
|
||||
.into_iter()
|
||||
|
@ -130,13 +130,10 @@ impl Api {
|
|||
state.add_valid_credential(cred);
|
||||
}
|
||||
|
||||
match state.verify() {
|
||||
AuthResult::Accepted { username } => {
|
||||
if let AuthResult::Accepted { username } = state.verify() {
|
||||
auth_state_store.complete(state.id()).await;
|
||||
authorize_session(req, username).await?;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Ok(Response::new(ReturnToSsoResponse::Ok).header(
|
||||
"Location",
|
||||
|
|
|
@ -51,13 +51,13 @@ impl Api {
|
|||
SessionAuthorization::Ticket { target_name, .. } => target_name == name,
|
||||
SessionAuthorization::User(_) => {
|
||||
let mut config_provider = services.config_provider.lock().await;
|
||||
match config_provider
|
||||
|
||||
matches!(
|
||||
config_provider
|
||||
.authorize_target(auth.username(), &name)
|
||||
.await
|
||||
{
|
||||
Ok(true) => true,
|
||||
_ => false,
|
||||
}
|
||||
.await,
|
||||
Ok(true)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,8 +79,7 @@ async fn get_target_for_request(
|
|||
TargetOptions::Http(ref options) => Some((t, options)),
|
||||
_ => None,
|
||||
})
|
||||
.filter(|(_, o)| o.external_host.as_deref() == Some(host))
|
||||
.next()
|
||||
.find(|(_, o)| o.external_host.as_deref() == Some(host))
|
||||
.map(|(t, _)| t.name.clone())
|
||||
} else {
|
||||
None
|
||||
|
@ -127,7 +126,7 @@ async fn get_target_for_request(
|
|||
.config_provider
|
||||
.lock()
|
||||
.await
|
||||
.authorize_target(&auth.username(), &target.0.name)
|
||||
.authorize_target(auth.username(), &target.0.name)
|
||||
.await?
|
||||
{
|
||||
return Ok(None);
|
||||
|
@ -137,5 +136,5 @@ async fn get_target_for_request(
|
|||
}
|
||||
}
|
||||
|
||||
return Ok(None);
|
||||
Ok(None)
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ impl SessionExt for Session {
|
|||
}
|
||||
|
||||
fn get_username(&self) -> Option<String> {
|
||||
return self.get_auth().map(|x| x.username().to_owned());
|
||||
self.get_auth().map(|x| x.username().to_owned())
|
||||
}
|
||||
|
||||
fn get_auth(&self) -> Option<SessionAuthorization> {
|
||||
|
@ -91,7 +91,7 @@ impl SessionAuthorization {
|
|||
}
|
||||
|
||||
async fn is_user_admin(req: &Request, auth: &SessionAuthorization) -> poem::Result<bool> {
|
||||
let services: Data<&Services> = <_>::from_request_without_body(&req).await?;
|
||||
let services: Data<&Services> = <_>::from_request_without_body(req).await?;
|
||||
|
||||
let SessionAuthorization::User(username) = auth else {
|
||||
return Ok(false)
|
||||
|
@ -102,7 +102,7 @@ async fn is_user_admin(req: &Request, auth: &SessionAuthorization) -> poem::Resu
|
|||
for target in targets {
|
||||
if matches!(target.options, TargetOptions::WebAdmin(_))
|
||||
&& config_provider
|
||||
.authorize_target(&username, &target.name)
|
||||
.authorize_target(username, &target.name)
|
||||
.await?
|
||||
{
|
||||
drop(config_provider);
|
||||
|
@ -169,7 +169,7 @@ pub fn gateway_redirect(req: &Request) -> Response {
|
|||
.original_uri()
|
||||
.path_and_query()
|
||||
.map(|p| p.to_string())
|
||||
.unwrap_or("".into());
|
||||
.unwrap_or_else(|| "".into());
|
||||
|
||||
let path = format!(
|
||||
"/@warpgate#/login?next={}",
|
||||
|
@ -184,20 +184,17 @@ pub async fn get_auth_state_for_request(
|
|||
session: &Session,
|
||||
store: &mut AuthStateStore,
|
||||
) -> Result<Arc<Mutex<AuthState>>, WarpgateError> {
|
||||
match session.get_auth_state_id() {
|
||||
Some(id) => {
|
||||
if let Some(id) = session.get_auth_state_id() {
|
||||
if !store.contains_key(&id.0) {
|
||||
session.remove(AUTH_STATE_ID_SESSION_KEY)
|
||||
}
|
||||
}
|
||||
None => (),
|
||||
};
|
||||
|
||||
match session.get_auth_state_id() {
|
||||
Some(id) => Ok(store.get(&id.0).unwrap()),
|
||||
Some(id) => Ok(store.get(&id.0).ok_or(WarpgateError::InconsistentState)?),
|
||||
None => {
|
||||
let (id, state) = store
|
||||
.create(&username, crate::common::PROTOCOL_NAME)
|
||||
.create(username, crate::common::PROTOCOL_NAME)
|
||||
.await?;
|
||||
session.set(AUTH_STATE_ID_SESSION_KEY, AuthStateId(id));
|
||||
Ok(state)
|
||||
|
@ -207,13 +204,13 @@ pub async fn get_auth_state_for_request(
|
|||
|
||||
pub async fn authorize_session(req: &Request, username: String) -> poem::Result<()> {
|
||||
let session_middleware: Data<&Arc<Mutex<SessionStore>>> =
|
||||
<_>::from_request_without_body(&req).await?;
|
||||
let session: &Session = <_>::from_request_without_body(&req).await?;
|
||||
<_>::from_request_without_body(req).await?;
|
||||
let session: &Session = <_>::from_request_without_body(req).await?;
|
||||
|
||||
let server_handle = session_middleware
|
||||
.lock()
|
||||
.await
|
||||
.create_handle_for(&req)
|
||||
.create_handle_for(req)
|
||||
.await?;
|
||||
server_handle
|
||||
.lock()
|
||||
|
|
|
@ -2,7 +2,7 @@ use http::StatusCode;
|
|||
use poem::IntoResponse;
|
||||
|
||||
pub fn error_page(e: poem::Error) -> impl IntoResponse {
|
||||
return poem::web::Html(format!(
|
||||
poem::web::Html(format!(
|
||||
r#"<!DOCTYPE html>
|
||||
<style>
|
||||
body {{
|
||||
|
@ -24,5 +24,5 @@ pub fn error_page(e: poem::Error) -> impl IntoResponse {
|
|||
<p>{e}</p>
|
||||
</main>
|
||||
"#
|
||||
)).with_status(StatusCode::BAD_GATEWAY);
|
||||
)).with_status(StatusCode::BAD_GATEWAY)
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ impl ProtocolServer for HTTPProtocolServer {
|
|||
crate::proxy::proxy_normal_request(&request, poem::Body::empty(), &options)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
return TargetTestError::ConnectionError(format!("{e}"));
|
||||
TargetTestError::ConnectionError(format!("{e}"))
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -62,7 +62,9 @@ impl SomeRequestBuilder for http::request::Builder {
|
|||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
static ref DONT_FORWARD_HEADERS: HashSet<HeaderName> = {
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
let mut s = HashSet::new();
|
||||
s.insert(http::header::ACCEPT_ENCODING);
|
||||
s.insert(http::header::SEC_WEBSOCKET_EXTENSIONS);
|
||||
|
@ -78,9 +80,9 @@ lazy_static::lazy_static! {
|
|||
};
|
||||
}
|
||||
|
||||
const X_FORWARDED_FOR: HeaderName = HeaderName::from_static("x-forwarded-for");
|
||||
const X_FORWARDED_HOST: HeaderName = HeaderName::from_static("x-forwarded-host");
|
||||
const X_FORWARDED_PROTO: HeaderName = HeaderName::from_static("x-forwarded-proto");
|
||||
static X_FORWARDED_FOR: HeaderName = HeaderName::from_static("x-forwarded-for");
|
||||
static X_FORWARDED_HOST: HeaderName = HeaderName::from_static("x-forwarded-host");
|
||||
static X_FORWARDED_PROTO: HeaderName = HeaderName::from_static("x-forwarded-proto");
|
||||
|
||||
fn construct_uri(req: &Request, options: &TargetHTTPOptions, websocket: bool) -> Result<Uri> {
|
||||
let target_uri = Uri::try_from(options.url.clone())?;
|
||||
|
@ -90,7 +92,7 @@ fn construct_uri(req: &Request, options: &TargetHTTPOptions, websocket: bool) ->
|
|||
.authority()
|
||||
.context("No authority in the URL")?
|
||||
.to_string();
|
||||
let authority = authority.split("@").last().context("Authority is empty")?;
|
||||
let authority = authority.split('@').last().context("Authority is empty")?;
|
||||
let authority: Authority = authority.try_into()?;
|
||||
let mut uri = http::uri::Builder::new()
|
||||
.authority(authority)
|
||||
|
@ -221,7 +223,7 @@ pub async fn proxy_normal_request(
|
|||
body: Body,
|
||||
options: &TargetHTTPOptions,
|
||||
) -> poem::Result<Response> {
|
||||
let uri = construct_uri(req, &options, false)?;
|
||||
let uri = construct_uri(req, options, false)?;
|
||||
|
||||
tracing::debug!("URI: {:?}", uri);
|
||||
|
||||
|
@ -257,8 +259,8 @@ pub async fn proxy_normal_request(
|
|||
|
||||
let mut client_request = client.request(req.method().into(), uri.to_string());
|
||||
|
||||
client_request = copy_server_request(&req, client_request);
|
||||
client_request = inject_forwarding_headers(&req, client_request)?;
|
||||
client_request = copy_server_request(req, client_request);
|
||||
client_request = inject_forwarding_headers(req, client_request)?;
|
||||
client_request = rewrite_request(client_request, options)?;
|
||||
client_request = client_request.body(reqwest::Body::wrap_stream(body.into_bytes_stream()));
|
||||
client_request = client_request.header(
|
||||
|
@ -273,7 +275,7 @@ pub async fn proxy_normal_request(
|
|||
.execute(client_request)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Could not execute request: {e}"))?;
|
||||
let status = client_response.status().clone();
|
||||
let status = client_response.status();
|
||||
|
||||
let mut response: Response = "".into();
|
||||
|
||||
|
@ -313,7 +315,7 @@ async fn copy_client_body_and_embed(
|
|||
r#"<script type="module" src="/@warpgate/{}"></script>"#,
|
||||
script_manifest.file
|
||||
);
|
||||
for css_file in script_manifest.css.unwrap_or(vec![]) {
|
||||
for css_file in script_manifest.css.unwrap_or_default() {
|
||||
inject += &format!(
|
||||
r#"<link rel="stylesheet" href="/@warpgate/{}" />"#,
|
||||
css_file
|
||||
|
@ -344,7 +346,7 @@ pub async fn proxy_websocket_request(
|
|||
ws: WebSocket,
|
||||
options: &TargetHTTPOptions,
|
||||
) -> poem::Result<impl IntoResponse> {
|
||||
let uri = construct_uri(req, &options, true)?;
|
||||
let uri = construct_uri(req, options, true)?;
|
||||
proxy_ws_inner(req, ws, uri.clone(), options)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
|
@ -375,8 +377,8 @@ async fn proxy_ws_inner(
|
|||
.to_string(),
|
||||
);
|
||||
|
||||
client_request = copy_server_request(&req, client_request);
|
||||
client_request = inject_forwarding_headers(&req, client_request)?;
|
||||
client_request = copy_server_request(req, client_request);
|
||||
client_request = inject_forwarding_headers(req, client_request)?;
|
||||
client_request = rewrite_request(client_request, options)?;
|
||||
|
||||
let (client, client_response) = connect_async_with_config(
|
||||
|
|
|
@ -97,16 +97,16 @@ impl SessionStore {
|
|||
&mut self,
|
||||
req: &Request,
|
||||
) -> poem::Result<WarpgateServerHandleFromRequest> {
|
||||
let session: &Session = <_>::from_request_without_body(&req).await?;
|
||||
let session: &Session = <_>::from_request_without_body(req).await?;
|
||||
|
||||
if let Some(handle) = self.handle_for(session) {
|
||||
return Ok(handle.into());
|
||||
}
|
||||
|
||||
let services = Data::<&Services>::from_request_without_body(&req).await?;
|
||||
let remote_address: &RemoteAddr = <_>::from_request_without_body(&req).await?;
|
||||
let services = Data::<&Services>::from_request_without_body(req).await?;
|
||||
let remote_address: &RemoteAddr = <_>::from_request_without_body(req).await?;
|
||||
let session_storage =
|
||||
Data::<&SharedSessionStorage>::from_request_without_body(&req).await?;
|
||||
Data::<&SharedSessionStorage>::from_request_without_body(req).await?;
|
||||
|
||||
let (session_handle, mut session_handle_rx) = HttpSessionHandle::new();
|
||||
|
||||
|
@ -134,13 +134,12 @@ impl SessionStore {
|
|||
tokio::spawn({
|
||||
let session_storage = (*session_storage).clone();
|
||||
let poem_session_id: Option<String> = session.get(POEM_SESSION_ID_SESSION_KEY);
|
||||
let id = id.clone();
|
||||
async move {
|
||||
while let Some(command) = session_handle_rx.recv().await {
|
||||
match command {
|
||||
SessionHandleCommand::Close => {
|
||||
if let Some(ref poem_session_id) = poem_session_id {
|
||||
let _ = session_storage.remove_session(&poem_session_id).await;
|
||||
let _ = session_storage.remove_session(poem_session_id).await;
|
||||
}
|
||||
info!(%id, "Removed HTTP session");
|
||||
let mut that = this.lock().await;
|
||||
|
|
|
@ -10,7 +10,7 @@ use warpgate_core::{SessionHandle, WarpgateServerHandle};
|
|||
|
||||
use crate::session::SessionStore;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum SessionHandleCommand {
|
||||
Close,
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ impl std::ops::Deref for WarpgateServerHandleFromRequest {
|
|||
impl<'a> FromRequest<'a> for WarpgateServerHandleFromRequest {
|
||||
async fn from_request(req: &'a Request, _: &mut RequestBody) -> poem::Result<Self> {
|
||||
let sm = Data::<&Arc<Mutex<SessionStore>>>::from_request_without_body(req).await?;
|
||||
let session: &Session = <_>::from_request_without_body(&req).await?;
|
||||
let session: &Session = <_>::from_request_without_body(req).await?;
|
||||
Ok(sm
|
||||
.lock()
|
||||
.await
|
||||
|
|
|
@ -69,7 +69,7 @@ pub async fn run_server(services: Services, address: SocketAddr) -> Result<()> {
|
|||
|
||||
let handler = ServerHandler { id, event_tx };
|
||||
|
||||
let session = match ServerSession::new(
|
||||
let session = match ServerSession::start(
|
||||
remote_address,
|
||||
&services,
|
||||
server_handle,
|
||||
|
|
|
@ -6,8 +6,8 @@ use bytes::Bytes;
|
|||
use tokio::sync::{broadcast, mpsc};
|
||||
|
||||
pub const ERASE_PROGRESS_SPINNER: &str = "\r \r";
|
||||
pub const ERASE_PROGRESS_SPINNER_BUF: Bytes = Bytes::from_static(ERASE_PROGRESS_SPINNER.as_bytes());
|
||||
pub const LINEBREAK: Bytes = Bytes::from_static("\n".as_bytes());
|
||||
pub const ERASE_PROGRESS_SPINNER_BUF: &[u8] = ERASE_PROGRESS_SPINNER.as_bytes();
|
||||
pub const LINEBREAK: &[u8] = "\n".as_bytes();
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ServiceOutput {
|
||||
|
@ -62,8 +62,8 @@ impl ServiceOutput {
|
|||
pub async fn hide_progress(&mut self) {
|
||||
self.progress_visible
|
||||
.store(false, std::sync::atomic::Ordering::Relaxed);
|
||||
self.emit_output(ERASE_PROGRESS_SPINNER_BUF);
|
||||
self.emit_output(LINEBREAK);
|
||||
self.emit_output(Bytes::from_static(ERASE_PROGRESS_SPINNER_BUF));
|
||||
self.emit_output(Bytes::from_static(LINEBREAK));
|
||||
}
|
||||
|
||||
pub fn subscribe(&self) -> broadcast::Receiver<Bytes> {
|
||||
|
|
|
@ -102,7 +102,7 @@ impl std::fmt::Debug for ServerSession {
|
|||
}
|
||||
|
||||
impl ServerSession {
|
||||
pub async fn new(
|
||||
pub async fn start(
|
||||
remote_address: SocketAddr,
|
||||
services: &Services,
|
||||
server_handle: Arc<Mutex<WarpgateServerHandle>>,
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"@otplib/preset-browser": "^12.0.1",
|
||||
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.49",
|
||||
"@tsconfig/svelte": "^3.0.0",
|
||||
"@types/qrcode": "^1.5.0",
|
||||
"@types/shell-escape": "^0.2.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.28.0",
|
||||
"@typescript-eslint/parser": "^5.28.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { Input } from 'sveltestrap'
|
||||
|
||||
import type { User, UserRequireCredentialsPolicy } from './lib/api'
|
||||
import type { CredentialKind, User, UserRequireCredentialsPolicy } from './lib/api'
|
||||
|
||||
export let user: User
|
||||
export let value: UserRequireCredentialsPolicy
|
||||
|
@ -39,7 +39,7 @@ function updateAny () {
|
|||
|
||||
function toggle (type: string) {
|
||||
if (value[protocolId].includes(type)) {
|
||||
value[protocolId] = value[protocolId].filter(x => x !== type)
|
||||
value[protocolId] = value[protocolId].filter((x: CredentialKind) => x !== type)
|
||||
} else {
|
||||
value[protocolId].push(type)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { api, UserSnapshot, Target, TicketAndSecret } from 'admin/lib/api'
|
||||
import { api, User, Target, TicketAndSecret } from 'admin/lib/api'
|
||||
import AsyncButton from 'common/AsyncButton.svelte'
|
||||
import ConnectionInstructions from 'common/ConnectionInstructions.svelte'
|
||||
import { TargetKind } from 'gateway/lib/api'
|
||||
|
@ -9,9 +9,9 @@ import { firstBy } from 'thenby'
|
|||
|
||||
let error: Error|null = null
|
||||
let targets: Target[]|undefined
|
||||
let users: UserSnapshot[]|undefined
|
||||
let users: User[]|undefined
|
||||
let selectedTarget: Target|undefined
|
||||
let selectedUser: UserSnapshot|undefined
|
||||
let selectedUser: User|undefined
|
||||
let result: TicketAndSecret|undefined
|
||||
|
||||
async function load () {
|
||||
|
|
|
@ -32,11 +32,11 @@ async function load () {
|
|||
}
|
||||
}
|
||||
|
||||
function deleteCredential (credential) {
|
||||
function deleteCredential (credential: UserAuthCredential) {
|
||||
user.credentials = user.credentials.filter(c => c !== credential)
|
||||
}
|
||||
|
||||
function abbreviatePublicKey (key) {
|
||||
function abbreviatePublicKey (key: string) {
|
||||
return key.slice(0, 16) + '...' + key.slice(-8)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { onMount } from 'svelte'
|
||||
import { Alert, Button, FormGroup, Input, Modal, ModalBody, ModalFooter, ModalHeader } from 'sveltestrap'
|
||||
import QRCode from 'qrcode'
|
||||
import { KeyEncodings, TOTP, TOTPOptions } from '@otplib/core'
|
||||
import { TOTP, TOTPOptions } from '@otplib/core'
|
||||
import { createDigest } from '@otplib/plugin-crypto-js'
|
||||
import { faRefresh } from '@fortawesome/free-solid-svg-icons'
|
||||
import Fa from 'svelte-fa'
|
||||
|
@ -60,9 +60,8 @@ $: {
|
|||
|
||||
const uri = totp.keyuri(username, 'Warpgate', base32Encode(new Uint8Array(credential.key), 'RFC4648'))
|
||||
|
||||
QRCode.toDataURL(uri, (err, imageUrl) => {
|
||||
QRCode.toDataURL(uri, (err: Error, imageUrl: string) => {
|
||||
if (err) {
|
||||
console.log('Error with QR')
|
||||
return
|
||||
}
|
||||
if (qrImage) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { faSignOut } from '@fortawesome/free-solid-svg-icons'
|
||||
import { Alert } from 'sveltestrap'
|
||||
import Fa from 'svelte-fa'
|
||||
import Router, { push } from 'svelte-spa-router'
|
||||
import Router, { push, RouteDetail } from 'svelte-spa-router'
|
||||
import { wrap } from 'svelte-spa-router/wrap'
|
||||
import { get } from 'svelte/store'
|
||||
import { api } from 'gateway/lib/api'
|
||||
|
@ -29,7 +29,7 @@ function onPageResume () {
|
|||
init()
|
||||
}
|
||||
|
||||
async function requireLogin (detail) {
|
||||
async function requireLogin (detail: RouteDetail) {
|
||||
await serverInfoPromise
|
||||
if (!get(serverInfo)?.username) {
|
||||
let url = detail.location
|
||||
|
|
|
@ -290,6 +290,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.6.tgz#f830323c88172e66826d0bde413498b61054b5a6"
|
||||
integrity sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==
|
||||
|
||||
"@types/qrcode@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/qrcode/-/qrcode-1.5.0.tgz#6a98fe9a9a7b2a9a3167b6dde17eff999eabe40b"
|
||||
integrity sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/sass@^1.16.0":
|
||||
version "1.43.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/sass/-/sass-1.43.1.tgz#86bb0168e9e881d7dade6eba16c9ed6d25dc2f68"
|
||||
|
|
|
@ -216,7 +216,7 @@ pub(crate) async fn command(cli: &crate::Cli) -> Result<()> {
|
|||
.await?
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or(anyhow::anyhow!("Database inconsistent: no admin role"))?;
|
||||
.ok_or_else(|| anyhow::anyhow!("Database inconsistent: no admin role"))?;
|
||||
|
||||
let admin_user = match User::Entity::find()
|
||||
.filter(User::Column::Username.eq(BUILTIN_ADMIN_USERNAME))
|
||||
|
|
Loading…
Reference in a new issue