Issue invite configs as subscription URLs with redeem-based lifetime.
Admin picks inbound once, sets duration in days from Get config, and configures the 3x-ui /sub base URL. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -84,6 +84,9 @@ def init_schema():
|
||||
cur.execute(
|
||||
"CREATE INDEX IF NOT EXISTS idx_users_xui_email ON users(xui_email)"
|
||||
)
|
||||
cur.execute(
|
||||
"ALTER TABLE invite_links ADD COLUMN IF NOT EXISTS duration_days INTEGER NOT NULL DEFAULT 0"
|
||||
)
|
||||
conn.commit()
|
||||
_schema_ready = True
|
||||
logger.info('PostgreSQL schema ready')
|
||||
|
||||
@@ -85,6 +85,7 @@ CREATE TABLE IF NOT EXISTS invite_links (
|
||||
xui_inbound_id INTEGER NOT NULL DEFAULT 0,
|
||||
password_hash TEXT,
|
||||
expires_at TIMESTAMPTZ,
|
||||
duration_days INTEGER NOT NULL DEFAULT 0,
|
||||
note TEXT,
|
||||
created_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
+6
-3
@@ -45,6 +45,7 @@ DEFAULT_SETTINGS = {
|
||||
'xui_server_id': 0,
|
||||
'xui_protocol': 'xray',
|
||||
'xui_inbound_id': 0,
|
||||
'xui_sub_url': '',
|
||||
},
|
||||
'guest': {
|
||||
'enabled': False,
|
||||
@@ -209,6 +210,7 @@ def _row_to_invite(row) -> dict:
|
||||
'xui_inbound_id': int(row['xui_inbound_id'] or 0),
|
||||
'password_hash': row['password_hash'],
|
||||
'expires_at': _ts_iso(row['expires_at']),
|
||||
'duration_days': int(row.get('duration_days') or 0),
|
||||
'note': row['note'] or '',
|
||||
'created_at': _ts_iso(row['created_at']),
|
||||
}
|
||||
@@ -252,7 +254,7 @@ def load_data() -> dict:
|
||||
cur.execute(
|
||||
'SELECT id, name, token, enabled, max_uses, used_count, user_id, '
|
||||
'protocol, server_id, xui_inbound_id, password_hash, expires_at, '
|
||||
'note, created_at FROM invite_links '
|
||||
'duration_days, note, created_at FROM invite_links '
|
||||
'ORDER BY created_at DESC NULLS LAST, name'
|
||||
)
|
||||
invite_links = [_row_to_invite(r) for r in cur.fetchall()]
|
||||
@@ -392,8 +394,8 @@ def save_data(data: dict) -> None:
|
||||
'INSERT INTO invite_links ('
|
||||
'id, name, token, enabled, max_uses, used_count, user_id, '
|
||||
'protocol, server_id, xui_inbound_id, password_hash, expires_at, '
|
||||
'note, created_at'
|
||||
') VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
|
||||
'duration_days, note, created_at'
|
||||
') VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
|
||||
(
|
||||
_as_uuid(link['id']),
|
||||
link.get('name') or '',
|
||||
@@ -407,6 +409,7 @@ def save_data(data: dict) -> None:
|
||||
int(link.get('xui_inbound_id') or 0),
|
||||
link.get('password_hash'),
|
||||
_parse_ts(link.get('expires_at')),
|
||||
int(link.get('duration_days') or 0),
|
||||
link.get('note') or '',
|
||||
_parse_ts(link.get('created_at')),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user