Enhance ticket creation api and UI to support ticket number of usage (#959)

Ticket uses left was already supported on core but no way to defined it,
neither from UI neither from API

Changed API to accept new optional field and update UI form to be able
to set it from UI

related #924

---

UI changes

<img width="1370" alt="Screenshot 2024-03-04 at 00 15 11"
src="https://github.com/warp-tech/warpgate/assets/275609/76510a58-e232-46af-bf50-9444e5950507">
<img width="1360" alt="Screenshot 2024-03-04 at 00 13 58"
src="https://github.com/warp-tech/warpgate/assets/275609/814d2ce2-6f6c-48eb-b066-ecec039530fc">

---------

Co-authored-by: Eugene <inbox@null.page>
This commit is contained in:
Thibaud Lepretre 2024-03-04 10:14:14 +01:00 committed by GitHub
parent 24f1b03bff
commit f3dc1ad668
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 26 additions and 2 deletions

View file

@ -24,7 +24,8 @@ enum GetTicketsResponse {
struct CreateTicketRequest {
username: String,
target_name: String,
expiry: Option<DateTime<Utc>>
expiry: Option<DateTime<Utc>>,
number_of_uses: Option<i32>
}
#[derive(Object)]
@ -87,6 +88,7 @@ impl Api {
target: Set(body.target_name.clone()),
created: Set(chrono::Utc::now()),
expiry: Set(body.expiry),
uses_left: Set(body.number_of_uses),
..Default::default()
};

View file

@ -13,6 +13,7 @@ let users: User[]|undefined
let selectedTarget: Target|undefined
let selectedUser: User|undefined
let selectedExpiry: string|undefined
let selectedNumberOfUses: number|undefined
let result: TicketAndSecret|undefined
async function load () {
@ -39,6 +40,7 @@ async function create () {
username: selectedUser.username,
targetName: selectedTarget.name,
expiry: selectedExpiry ? new Date(selectedExpiry) : undefined,
numberOfUses: selectedNumberOfUses
},
})
} catch (err) {
@ -110,6 +112,10 @@ async function create () {
<input type="datetime-local" bind:value={selectedExpiry} class="form-control"/>
</FormGroup>
<FormGroup floating label="Number of uses (optional)">
<input type="number" min="1" bind:value={selectedNumberOfUses} class="form-control"/>
</FormGroup>
<AsyncButton
outline
click={create}

View file

@ -4,7 +4,7 @@ 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'
import { faCalendarXmark, faCalendarCheck, faSquareXmark, faSquareCheck } from '@fortawesome/free-solid-svg-icons'
let error: Error|undefined
let tickets: Ticket[]|undefined
@ -55,6 +55,18 @@ async function deleteTicket (ticket: Ticket) {
<Fa icon={ticket.expiry > new Date() ? faCalendarCheck : faCalendarXmark} fw /> Until {ticket.expiry?.toLocaleString()}
</small>
{/if}
{#if ticket.usesLeft != null}
{#if ticket.usesLeft > 0}
<small class="text-muted ms-4">
<Fa icon={faSquareCheck} fw /> Uses left: {ticket.usesLeft}
</small>
{/if}
{#if ticket.usesLeft === 0}
<small class="text-danger ms-4">
<Fa icon={faSquareXmark} fw /> Used up
</small>
{/if}
{/if}
<small class="text-muted me-4 ms-auto">
<RelativeDate date={ticket.created} />
</small>

View file

@ -1127,6 +1127,10 @@
"expiry": {
"type": "string",
"format": "date-time"
},
"number_of_uses": {
"type": "integer",
"format": "int32"
}
}
},