mirror of
https://github.com/warp-tech/warpgate.git
synced 2024-09-20 06:46:17 +08:00
Enhance ticket creation api and UI to support ticket expiry (#957)
Ticket expiry was already supported on core but no way to defined it, neither from UI neither from API Changed API to accept new optional field `expiry` and update UI form to be able to set it from UI closes #924
This commit is contained in:
parent
4a833c5559
commit
257fb38a21
|
@ -96,6 +96,10 @@ The binary is in `target/{debug|release}`.
|
|||
* Svelte
|
||||
* Bootstrap
|
||||
|
||||
### Backend API
|
||||
|
||||
* Warpgate admin and user facing APIs use autogenerated OpenAPI schemas and SDKs. To update the SDKs after changing the query/response structures, run `just openapi-all`.
|
||||
|
||||
## Contributors ✨
|
||||
|
||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Context;
|
||||
use chrono::{DateTime, Utc};
|
||||
use poem::web::Data;
|
||||
use poem_openapi::payload::Json;
|
||||
use poem_openapi::{ApiResponse, Object, OpenApi};
|
||||
|
@ -23,6 +24,7 @@ enum GetTicketsResponse {
|
|||
struct CreateTicketRequest {
|
||||
username: String,
|
||||
target_name: String,
|
||||
expiry: Option<DateTime<Utc>>
|
||||
}
|
||||
|
||||
#[derive(Object)]
|
||||
|
@ -84,7 +86,7 @@ impl Api {
|
|||
username: Set(body.username.clone()),
|
||||
target: Set(body.target_name.clone()),
|
||||
created: Set(chrono::Utc::now()),
|
||||
expiry: Set(None),
|
||||
expiry: Set(body.expiry),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ let targets: Target[]|undefined
|
|||
let users: User[]|undefined
|
||||
let selectedTarget: Target|undefined
|
||||
let selectedUser: User|undefined
|
||||
let selectedExpiry: string|undefined
|
||||
let result: TicketAndSecret|undefined
|
||||
|
||||
async function load () {
|
||||
|
@ -37,6 +38,7 @@ async function create () {
|
|||
createTicketRequest: {
|
||||
username: selectedUser.username,
|
||||
targetName: selectedTarget.name,
|
||||
expiry: selectedExpiry ? new Date(selectedExpiry) : undefined,
|
||||
},
|
||||
})
|
||||
} catch (err) {
|
||||
|
@ -75,6 +77,7 @@ async function create () {
|
|||
use:link
|
||||
>Done</a>
|
||||
{:else}
|
||||
<div class="narrow-page">
|
||||
<div class="page-summary-bar">
|
||||
<h1>Create an access ticket</h1>
|
||||
</div>
|
||||
|
@ -103,8 +106,13 @@ async function create () {
|
|||
</FormGroup>
|
||||
{/if}
|
||||
|
||||
<FormGroup floating label="Expiry (optional)">
|
||||
<input type="datetime-local" bind:value={selectedExpiry} class="form-control"/>
|
||||
</FormGroup>
|
||||
|
||||
<AsyncButton
|
||||
outline
|
||||
click={create}
|
||||
>Create ticket</AsyncButton>
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
@ -3,6 +3,8 @@ import { api, Ticket } from 'admin/lib/api'
|
|||
import { link } from 'svelte-spa-router'
|
||||
import { Alert } from 'sveltestrap'
|
||||
import RelativeDate from './RelativeDate.svelte'
|
||||
import Fa from 'svelte-fa'
|
||||
import { faCalendarXmark, faCalendarCheck } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
let error: Error|undefined
|
||||
let tickets: Ticket[]|undefined
|
||||
|
@ -45,10 +47,15 @@ async function deleteTicket (ticket: Ticket) {
|
|||
<div class="list-group list-group-flush">
|
||||
{#each tickets as ticket}
|
||||
<div class="list-group-item">
|
||||
<strong class="me-auto">
|
||||
<strong>
|
||||
Access to {ticket.target} as {ticket.username}
|
||||
</strong>
|
||||
<small class="text-muted me-4">
|
||||
{#if ticket.expiry}
|
||||
<small class="text-muted ms-4">
|
||||
<Fa icon={ticket.expiry > new Date() ? faCalendarCheck : faCalendarXmark} fw /> Until {ticket.expiry?.toLocaleString()}
|
||||
</small>
|
||||
{/if}
|
||||
<small class="text-muted me-4 ms-auto">
|
||||
<RelativeDate date={ticket.created} />
|
||||
</small>
|
||||
<a href={''} on:click|preventDefault={() => deleteTicket(ticket)}>Delete</a>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Warpgate Web Admin",
|
||||
"version": "0.7.4"
|
||||
"version": "0.9.1"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
|
@ -1123,6 +1123,10 @@
|
|||
},
|
||||
"target_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"expiry": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Warpgate HTTP proxy",
|
||||
"version": "0.7.4"
|
||||
"version": "0.9.1"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
@use "sass:map";
|
||||
|
||||
// Layout & components
|
||||
@import "bootstrap/scss/root";
|
||||
@import "bootstrap/scss/reboot";
|
||||
|
@ -101,3 +103,9 @@ input:-webkit-autofill:focus {
|
|||
.form-floating>.form-control:not(:focus)::placeholder {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
.narrow-page {
|
||||
width: map.get($grid-breakpoints, "md");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue