Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
V
vidai
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
SexHackMe
vidai
Commits
2430ec95
Commit
2430ec95
authored
Oct 06, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move api_tokens.html and settings.html to admin/ directory and update template paths
parent
bc4f1af3
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
434 additions
and
6 deletions
+434
-6
api_tokens.html
templates/admin/api_tokens.html
+249
-0
settings.html
templates/admin/settings.html
+179
-0
web.py
vidai/web.py
+6
-6
No files found.
templates/admin/api_tokens.html
0 → 100644
View file @
2430ec95
{% extends "base.html" %}
{% block title %}API Tokens - VidAI{% endblock %}
{% block head %}
<style>
.container
{
max-width
:
1200px
;
margin
:
2rem
auto
;
padding
:
0
2rem
;
}
.tokens-card
{
background
:
white
;
padding
:
2rem
;
border-radius
:
12px
;
box-shadow
:
0
2px
10px
rgba
(
0
,
0
,
0
,
0.05
);
margin-bottom
:
2rem
;
}
.card-header
{
margin-bottom
:
1.5rem
;
}
.card-header
h3
{
margin
:
0
;
color
:
#1e293b
;
}
.form-group
{
margin-bottom
:
1.5rem
;
}
.form-group
label
{
display
:
block
;
margin-bottom
:
0.5rem
;
color
:
#374151
;
font-weight
:
500
;
}
.form-group
input
{
width
:
100%
;
padding
:
0.75rem
;
border
:
2px
solid
#e5e7eb
;
border-radius
:
8px
;
font-size
:
1rem
;
}
.form-group
input
:focus
{
outline
:
none
;
border-color
:
#667eea
;
}
.btn
{
padding
:
0.75rem
2rem
;
background
:
#667eea
;
color
:
white
;
border
:
none
;
border-radius
:
8px
;
font-size
:
1rem
;
font-weight
:
600
;
cursor
:
pointer
;
}
.btn
:hover
{
background
:
#5a67d8
;
}
.btn-danger
{
background
:
#dc2626
;
}
.btn-danger
:hover
{
background
:
#b91c1c
;
}
.alert
{
padding
:
0.75rem
;
border-radius
:
8px
;
margin-bottom
:
1rem
;
}
.alert-error
{
background
:
#fee2e2
;
color
:
#dc2626
;
border
:
1px
solid
#fecaca
;
}
.alert-success
{
background
:
#d1fae5
;
color
:
#065f46
;
border
:
1px
solid
#a7f3d0
;
}
.token-display
{
background
:
#f8fafc
;
padding
:
1rem
;
border-radius
:
8px
;
border
:
1px
solid
#e5e7eb
;
margin
:
1rem
0
;
}
.token-display
pre
{
word-break
:
break-all
;
white-space
:
pre-wrap
;
font-family
:
monospace
;
background
:
white
;
padding
:
1rem
;
border-radius
:
4px
;
border
:
1px
solid
#d1d5db
;
}
.copy-btn
{
margin-top
:
0.5rem
;
padding
:
0.5rem
1rem
;
font-size
:
0.9rem
;
}
.table
{
width
:
100%
;
border-collapse
:
collapse
;
margin-top
:
1rem
;
}
.table
th
,
.table
td
{
padding
:
1rem
;
text-align
:
left
;
border-bottom
:
1px
solid
#e5e7eb
;
}
.table
th
{
background
:
#f8fafc
;
font-weight
:
600
;
color
:
#374151
;
}
.status-active
{
color
:
#065f46
;
font-weight
:
500
;
}
.status-inactive
{
color
:
#dc2626
;
font-weight
:
500
;
}
.modal
{
display
:
none
;
position
:
fixed
;
z-index
:
1000
;
left
:
0
;
top
:
0
;
width
:
100%
;
height
:
100%
;
background-color
:
rgba
(
0
,
0
,
0
,
0.5
);
}
.modal-content
{
background-color
:
white
;
position
:
fixed
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
padding
:
2rem
;
width
:
90%
;
max-width
:
500px
;
border-radius
:
12px
;
}
.modal-header
{
margin-bottom
:
1rem
;
position
:
relative
;
}
.modal-footer
{
text-align
:
right
;
margin-top
:
1.5rem
;
}
.close
{
position
:
absolute
;
top
:
0
;
right
:
0
;
cursor
:
pointer
;
font-size
:
1.5rem
;
line-height
:
1
;
}
</style>
{% endblock %}
{% block content %}
<div
class=
"container"
>
<div
class=
"tokens-card"
>
<div
class=
"card-header"
>
<h3><i
class=
"fas fa-key"
></i>
Your API Tokens
</h3>
<button
onclick=
"openAddTokenModal()"
class=
"btn"
style=
"margin-left: auto;"
><i
class=
"fas fa-plus"
></i>
Add Token
</button>
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div
class=
"alert alert-{{ 'error' if category == 'error' else 'success' }}"
>
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div
class=
"tokens-card"
>
<div
class=
"card-header"
>
<h3><i
class=
"fas fa-key"
></i>
Your API Tokens
</h3>
</div>
<table
class=
"table"
>
<thead>
<tr>
<th>
Name
</th>
<th>
Created
</th>
<th>
Last Used
</th>
<th>
Status
</th>
<th>
Actions
</th>
</tr>
</thead>
<tbody>
{% for token in user_tokens %}
<tr>
<td>
{{ token.get('name') }}
</td>
<td>
{{ token.get('created_at', 'N/A')[:19] if token.get('created_at') else 'N/A' }}
</td>
<td>
{{ token.get('last_used', 'Never')[:19] if token.get('last_used') else 'Never' }}
</td>
<td><span
class=
"status-{{ 'active' if token.get('active') else 'inactive' }}"
>
{{ 'Active' if token.get('active') else 'Inactive' }}
</span></td>
<td>
<button
onclick=
"deleteToken({{ token.get('id') }}, '{{ token.get('name') }}')"
class=
"btn btn-danger"
style=
"padding: 0.5rem 1rem; font-size: 0.9rem;"
>
Delete
</button>
</td>
</tr>
{% endfor %}
{% if not user_tokens %}
<tr>
<td
colspan=
"5"
style=
"text-align: center; color: #6b7280;"
>
No API tokens found. Generate your first token above.
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
<!-- Add Token Modal -->
<div
id=
"addTokenModal"
class=
"modal"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<h3><i
class=
"fas fa-plus"
></i>
Generate New API Token
</h3>
<span
class=
"close"
onclick=
"closeAddTokenModal()"
>
×
</span>
</div>
<form
method=
"post"
action=
"/api_tokens/generate"
>
<div
class=
"modal-body"
>
<div
class=
"form-group"
>
<label
for=
"modal_token_name"
>
Token Name
</label>
<input
type=
"text"
id=
"modal_token_name"
name=
"token_name"
placeholder=
"e.g., My App Token"
required
>
</div>
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
onclick=
"closeAddTokenModal()"
class=
"btn"
style=
"background: #6b7280;"
>
Cancel
</button>
<button
type=
"submit"
class=
"btn"
>
Generate Token
</button>
</div>
</form>
</div>
</div>
<!-- Token Generated Modal -->
{% if generated_token %}
<div
id=
"tokenModal"
class=
"modal"
style=
"display: block;"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<h3>
API Token Generated Successfully!
</h3>
<span
class=
"close"
onclick=
"closeTokenModal()"
>
×
</span>
</div>
<div
class=
"modal-body"
>
<p><strong>
Token Name:
</strong>
{{ token_name }}
</p>
<p><strong>
Token:
</strong></p>
<div
class=
"token-display"
style=
"margin: 1rem 0;"
>
<pre
id=
"modalTokenText"
>
{{ generated_token }}
</pre>
<button
class=
"btn copy-btn"
onclick=
"copyTokenFromModal()"
>
Copy Token
</button>
</div>
<p
style=
"color: #dc2626; font-weight: 500;"
>
Copy this token now. You won't be able to see it again!
</p>
</div>
<div
class=
"modal-footer"
>
<button
onclick=
"closeTokenModal()"
class=
"btn"
>
Close
</button>
</div>
</div>
</div>
{% endif %}
<!-- Delete Confirmation Modal -->
<div
id=
"deleteModal"
class=
"modal"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<h3>
Delete API Token
</h3>
</div>
<div
class=
"modal-body"
>
<p>
Are you sure you want to delete the token "
<span
id=
"deleteTokenName"
></span>
"?
</p>
<p
style=
"color: #dc2626; font-weight: 500;"
>
This action cannot be undone. Any applications using this token will stop working.
</p>
</div>
<div
class=
"modal-footer"
>
<button
onclick=
"closeDeleteModal()"
class=
"btn"
style=
"background: #6b7280;"
>
Cancel
</button>
<form
id=
"deleteForm"
method=
"post"
action=
""
style=
"display: inline;"
>
<button
type=
"submit"
class=
"btn btn-danger"
>
Delete Token
</button>
</form>
</div>
</div>
</div>
<script>
function
copyToken
()
{
const
tokenText
=
document
.
getElementById
(
'tokenText'
);
navigator
.
clipboard
.
writeText
(
tokenText
.
textContent
).
then
(
function
()
{
alert
(
'Token copied to clipboard!'
);
},
function
(
err
)
{
// Fallback for older browsers
const
textArea
=
document
.
createElement
(
'textarea'
);
textArea
.
value
=
tokenText
.
textContent
;
document
.
body
.
appendChild
(
textArea
);
textArea
.
select
();
document
.
execCommand
(
'copy'
);
document
.
body
.
removeChild
(
textArea
);
alert
(
'Token copied to clipboard!'
);
});
}
function
deleteToken
(
tokenId
,
tokenName
)
{
document
.
getElementById
(
'deleteTokenName'
).
textContent
=
tokenName
;
document
.
getElementById
(
'deleteForm'
).
action
=
`/api_tokens/delete/
${
tokenId
}
`
;
document
.
getElementById
(
'deleteModal'
).
style
.
display
=
'block'
;
}
function
closeDeleteModal
()
{
document
.
getElementById
(
'deleteModal'
).
style
.
display
=
'none'
;
}
function
openAddTokenModal
()
{
const
modal
=
document
.
getElementById
(
'addTokenModal'
);
modal
.
style
.
display
=
'block'
;
}
function
closeAddTokenModal
()
{
const
modal
=
document
.
getElementById
(
'addTokenModal'
);
modal
.
style
.
display
=
'none'
;
}
function
closeTokenModal
()
{
document
.
getElementById
(
'tokenModal'
).
style
.
display
=
'none'
;
window
.
location
.
href
=
'/api_tokens'
;
// Redirect to avoid POST resubmission
}
function
copyTokenFromModal
()
{
const
tokenText
=
document
.
getElementById
(
'modalTokenText'
);
const
copyBtn
=
document
.
querySelector
(
'#tokenModal .copy-btn'
);
const
originalText
=
copyBtn
.
textContent
;
// Use execCommand for reliable copying
const
textArea
=
document
.
createElement
(
'textarea'
);
textArea
.
value
=
tokenText
.
textContent
.
trim
();
document
.
body
.
appendChild
(
textArea
);
textArea
.
select
();
try
{
document
.
execCommand
(
'copy'
);
copyBtn
.
textContent
=
'Copied!'
;
copyBtn
.
style
.
background
=
'#10b981'
;
setTimeout
(
function
()
{
copyBtn
.
textContent
=
originalText
;
copyBtn
.
style
.
background
=
''
;
},
2000
);
}
catch
(
err
)
{
alert
(
'Failed to copy token. Please select and copy manually.'
);
}
document
.
body
.
removeChild
(
textArea
);
}
// Close modal when clicking outside
window
.
onclick
=
function
(
event
)
{
const
addModal
=
document
.
getElementById
(
'addTokenModal'
);
if
(
addModal
&&
event
.
target
==
addModal
)
{
closeAddTokenModal
();
}
const
deleteModal
=
document
.
getElementById
(
'deleteModal'
);
if
(
deleteModal
&&
event
.
target
==
deleteModal
)
{
closeDeleteModal
();
}
const
tokenModal
=
document
.
getElementById
(
'tokenModal'
);
if
(
tokenModal
&&
event
.
target
==
tokenModal
)
{
closeTokenModal
();
}
// Close user dropdown
const
dropdown
=
document
.
getElementById
(
'userDropdown'
);
const
icon
=
document
.
querySelector
(
'.user-icon'
);
if
(
dropdown
&&
icon
&&
!
icon
.
contains
(
event
.
target
)
&&
!
dropdown
.
contains
(
event
.
target
))
{
dropdown
.
style
.
display
=
'none'
;
}
}
function
toggleUserMenu
()
{
const
dropdown
=
document
.
getElementById
(
'userDropdown'
);
dropdown
.
style
.
display
=
dropdown
.
style
.
display
===
'block'
?
'none'
:
'block'
;
}
</script>
{% endblock %}
\ No newline at end of file
templates/admin/settings.html
0 → 100644
View file @
2430ec95
<!DOCTYPE html>
<html>
<head>
<title>
Settings - VidAI
</title>
<link
href=
"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
rel=
"stylesheet"
>
<link
rel=
"stylesheet"
href=
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"
>
<style>
*
{
margin
:
0
;
padding
:
0
;
box-sizing
:
border-box
;
}
body
{
font-family
:
'Inter'
,
sans-serif
;
background
:
#f8fafc
;
}
.header
{
background
:
white
;
padding
:
1rem
2rem
;
box-shadow
:
0
1px
3px
rgba
(
0
,
0
,
0
,
0.1
);
}
.header-content
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
max-width
:
1200px
;
margin
:
0
auto
;
}
.logo
{
font-size
:
1.5rem
;
font-weight
:
700
;
color
:
#667eea
;
}
.nav
{
display
:
flex
;
gap
:
2rem
;
}
.nav
a
{
text-decoration
:
none
;
color
:
#64748b
;
font-weight
:
500
;
}
.nav
a
.active
{
color
:
#667eea
;
}
.user-menu
{
display
:
flex
;
align-items
:
center
;
gap
:
1rem
;
position
:
relative
;
}
.user-icon
{
cursor
:
pointer
;
padding
:
0.5rem
;
border-radius
:
50%
;
background
:
#f8fafc
;
transition
:
background
0.2s
;
}
.user-icon
:hover
{
background
:
#e2e8f0
;
}
.user-icon
i
{
font-size
:
1.2rem
;
color
:
#64748b
;
}
.user-dropdown
{
display
:
none
;
position
:
absolute
;
top
:
100%
;
right
:
0
;
background
:
white
;
min-width
:
200px
;
box-shadow
:
0
4px
12px
rgba
(
0
,
0
,
0
,
0.15
);
border-radius
:
8px
;
z-index
:
1000
;
}
.user-dropdown
a
{
display
:
block
;
padding
:
0.75rem
1rem
;
text-decoration
:
none
;
color
:
#374151
;
border-bottom
:
1px
solid
#f1f5f9
;
}
.user-dropdown
a
:last-child
{
border-bottom
:
none
;
color
:
#dc2626
;
}
.user-dropdown
a
:hover
{
background
:
#f8fafc
;
}
.container
{
max-width
:
800px
;
margin
:
2rem
auto
;
padding
:
0
2rem
;
}
.settings-card
{
background
:
white
;
padding
:
2rem
;
border-radius
:
12px
;
box-shadow
:
0
2px
10px
rgba
(
0
,
0
,
0
,
0.05
);
margin-bottom
:
2rem
;
}
.card-header
{
margin-bottom
:
1.5rem
;
}
.card-header
h3
{
margin
:
0
;
color
:
#1e293b
;
}
.form-group
{
margin-bottom
:
1.5rem
;
}
.form-group
label
{
display
:
block
;
margin-bottom
:
0.5rem
;
color
:
#374151
;
font-weight
:
500
;
}
.form-group
input
,
.form-group
select
{
width
:
100%
;
padding
:
0.75rem
;
border
:
2px
solid
#e5e7eb
;
border-radius
:
8px
;
font-size
:
1rem
;
}
.form-group
input
:focus
,
.form-group
select
:focus
{
outline
:
none
;
border-color
:
#667eea
;
}
.btn
{
padding
:
0.75rem
2rem
;
background
:
#667eea
;
color
:
white
;
border
:
none
;
border-radius
:
8px
;
font-size
:
1rem
;
font-weight
:
600
;
cursor
:
pointer
;
}
.btn
:hover
{
background
:
#5a67d8
;
}
.alert
{
padding
:
0.75rem
;
border-radius
:
8px
;
margin-bottom
:
1rem
;
}
.alert-error
{
background
:
#fee2e2
;
color
:
#dc2626
;
border
:
1px
solid
#fecaca
;
}
.alert-success
{
background
:
#d1fae5
;
color
:
#065f46
;
border
:
1px
solid
#a7f3d0
;
}
.user-info
{
background
:
#f0f9ff
;
padding
:
1.5rem
;
border-radius
:
8px
;
border-left
:
4px
solid
#667eea
;
margin-bottom
:
2rem
;
}
</style>
</head>
<body>
<header
class=
"header"
>
<div
class=
"header-content"
>
<div
class=
"logo"
>
VidAI
</div>
<nav
class=
"nav"
>
<a
href=
"/dashboard"
>
Dashboard
</a>
<a
href=
"/analyze"
>
Analyze
</a>
<a
href=
"/train"
>
Train
</a>
<a
href=
"/history"
>
History
</a>
<a
href=
"/api_tokens"
>
API Tokens
</a>
<a
href=
"/settings"
class=
"active"
>
Settings
</a>
</nav>
<div
class=
"user-menu"
>
<div
class=
"user-icon"
onclick=
"toggleUserMenu()"
>
<i
class=
"fas fa-user"
></i>
</div>
<div
id=
"userDropdown"
class=
"user-dropdown"
>
<a
href=
"/account"
>
Account
</a>
{% if user.get('role') != 'admin' %}
<a
href=
"/api_tokens"
>
Tokens
</a>
{% else %}
<a
href=
"/admin/users"
>
Users
</a>
<a
href=
"/config"
>
Configurations
</a>
{% endif %}
<a
href=
"/logout"
>
Logout
</a>
</div>
</div>
</div>
</header>
<div
class=
"container"
>
<div
class=
"user-info"
>
<h3><i
class=
"fas fa-user"
></i>
Account Information
</h3>
<p><strong>
Username:
</strong>
{{ user['username'] }}
</p>
<p><strong>
Email:
</strong>
{{ user.get('email', 'Not provided') }}
</p>
<p><strong>
Role:
</strong>
{{ user.get('role', 'user').title() }}
</p>
<p><strong>
Member since:
</strong>
{{ user.get('created_at', 'Unknown')[:10] if user.get('created_at') else 'Unknown' }}
</p>
</div>
<div
class=
"settings-card"
>
<div
class=
"card-header"
>
<h3><i
class=
"fas fa-cog"
></i>
Application Settings
</h3>
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div
class=
"alert alert-{{ 'error' if category == 'error' else 'success' }}"
>
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
<form
method=
"post"
action=
"/update_settings"
>
<div
class=
"form-group"
>
<label
for=
"default_model"
>
Default AI Model
</label>
<input
type=
"text"
id=
"default_model"
name=
"default_model"
value=
"Qwen/Qwen2.5-VL-7B-Instruct"
placeholder=
"Model path or HuggingFace ID"
>
</div>
<div
class=
"form-group"
>
<label
for=
"theme"
>
Theme Preference
</label>
<select
id=
"theme"
name=
"theme"
>
<option
value=
"light"
selected
>
Light
</option>
<option
value=
"dark"
>
Dark
</option>
</select>
</div>
<button
type=
"submit"
class=
"btn"
><i
class=
"fas fa-save"
></i>
Save Settings
</button>
</form>
</div>
<div
class=
"settings-card"
>
<div
class=
"card-header"
>
<h3><i
class=
"fas fa-database"
></i>
Database Settings
</h3>
</div>
<form
method=
"post"
action=
"/update_database_settings"
>
<div
class=
"form-group"
>
<label
for=
"db_type"
>
Database Type
</label>
<select
id=
"db_type"
name=
"db_type"
>
<option
value=
"sqlite"
selected
>
SQLite
</option>
<option
value=
"mysql"
>
MySQL
</option>
</select>
</div>
<div
class=
"form-group"
>
<label
for=
"db_host"
>
Database Host
</label>
<input
type=
"text"
id=
"db_host"
name=
"db_host"
value=
"localhost"
>
</div>
<div
class=
"form-group"
>
<label
for=
"db_port"
>
Database Port
</label>
<input
type=
"number"
id=
"db_port"
name=
"db_port"
value=
"3306"
>
</div>
<div
class=
"form-group"
>
<label
for=
"db_name"
>
Database Name
</label>
<input
type=
"text"
id=
"db_name"
name=
"db_name"
value=
"vidai"
>
</div>
<div
class=
"form-group"
>
<label
for=
"db_user"
>
Database User
</label>
<input
type=
"text"
id=
"db_user"
name=
"db_user"
>
</div>
<div
class=
"form-group"
>
<label
for=
"db_password"
>
Database Password
</label>
<input
type=
"password"
id=
"db_password"
name=
"db_password"
>
</div>
<button
type=
"submit"
class=
"btn"
><i
class=
"fas fa-save"
></i>
Update Database Settings
</button>
</form>
</div>
<div
class=
"settings-card"
>
<div
class=
"card-header"
>
<h3><i
class=
"fas fa-server"
></i>
Worker Tokens
</h3>
</div>
<p>
Generate authentication tokens for worker processes (--client mode).
</p>
<a
href=
"/generate_worker_token"
class=
"btn"
style=
"background: #f59e0b;"
><i
class=
"fas fa-plus"
></i>
Generate Worker Token
</a>
</div>
</div>
<script>
function
toggleUserMenu
()
{
const
dropdown
=
document
.
getElementById
(
'userDropdown'
);
dropdown
.
style
.
display
=
dropdown
.
style
.
display
===
'block'
?
'none'
:
'block'
;
}
// Close dropdown when clicking outside
window
.
onclick
=
function
(
event
)
{
const
dropdown
=
document
.
getElementById
(
'userDropdown'
);
const
icon
=
document
.
querySelector
(
'.user-icon'
);
if
(
!
icon
.
contains
(
event
.
target
)
&&
!
dropdown
.
contains
(
event
.
target
))
{
dropdown
.
style
.
display
=
'none'
;
}
}
</script>
</body>
</html>
\ No newline at end of file
vidai/web.py
View file @
2430ec95
...
...
@@ -395,10 +395,10 @@ def settings():
"""User settings page."""
user
=
get_current_user_session
()
return
render_template
(
'settings.html'
,
user
=
user
,
tokens
=
get_user_tokens
(
user
[
"id"
]),
active_page
=
'settings'
)
return
render_template
(
'
admin/
settings.html'
,
user
=
user
,
tokens
=
get_user_tokens
(
user
[
"id"
]),
active_page
=
'settings'
)
@
app
.
route
(
'/update_settings'
,
methods
=
[
'POST'
])
@
login_required
...
...
@@ -425,7 +425,7 @@ def api_tokens():
user
=
get_current_user_session
()
from
.database
import
get_user_api_tokens
user_tokens
=
get_user_api_tokens
(
user
[
'id'
])
return
render_template
(
'api_tokens.html'
,
user
=
user
,
user_tokens
=
user_tokens
,
active_page
=
'api_tokens'
)
return
render_template
(
'a
dmin/a
pi_tokens.html'
,
user
=
user
,
user_tokens
=
user_tokens
,
active_page
=
'api_tokens'
)
@
app
.
route
(
'/api_tokens/generate'
,
methods
=
[
'POST'
])
@
login_required
...
...
@@ -450,7 +450,7 @@ def generate_api_token():
# Return with modal data instead of flash
from
.database
import
get_user_api_tokens
user_tokens
=
get_user_api_tokens
(
user
[
'id'
])
return
render_template
(
'api_tokens.html'
,
user
=
user
,
user_tokens
=
user_tokens
,
generated_token
=
token
,
token_name
=
token_name
,
show_modal
=
True
,
active_page
=
'api_tokens'
)
return
render_template
(
'a
dmin/a
pi_tokens.html'
,
user
=
user
,
user_tokens
=
user_tokens
,
generated_token
=
token
,
token_name
=
token_name
,
show_modal
=
True
,
active_page
=
'api_tokens'
)
@
app
.
route
(
'/api_tokens/delete/<int:token_id>'
,
methods
=
[
'POST'
])
@
login_required
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment