edit.tpl 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. {include file='user/header.tpl'}
  2. <script src="//{$config['jsdelivr_url']}/npm/jquery/dist/jquery.min.js"></script>
  3. <div class="page-wrapper">
  4. <div class="container-xl">
  5. <div class="page-header d-print-none text-white">
  6. <div class="row align-items-center">
  7. <div class="col">
  8. <h2 class="page-title">
  9. <span class="home-title">资料修改</span>
  10. </h2>
  11. <div class="page-pretitle my-3">
  12. <span class="home-subtitle">修改账户的部分信息</span>
  13. </div>
  14. </div>
  15. </div>
  16. </div>
  17. </div>
  18. <div class="page-body">
  19. <div class="container-xl">
  20. <div class="row row-deck row-cards">
  21. <div class="col-12">
  22. <div class="card">
  23. <ul class="nav nav-tabs nav-fill" data-bs-toggle="tabs" role="tablist">
  24. <li class="nav-item" role="presentation">
  25. <a href="#personal_information" class="nav-link active" data-bs-toggle="tab"
  26. aria-selected="true" role="tab">
  27. <i class="ti ti-chart-candle icon"></i>&nbsp;
  28. 资料
  29. </a>
  30. </li>
  31. <li class="nav-item" role="presentation">
  32. <a href="#login_security" class="nav-link" data-bs-toggle="tab" aria-selected="true"
  33. role="tab">
  34. <i class="ti ti-shield-lock icon"></i>&nbsp;
  35. 登录
  36. </a>
  37. </li>
  38. <li class="nav-item" role="presentation">
  39. <a href="#use_safety" class="nav-link" data-bs-toggle="tab" aria-selected="false"
  40. tabindex="-1" role="tab">
  41. <i class="ti ti-brand-telegram icon"></i>&nbsp;
  42. 使用
  43. </a>
  44. </li>
  45. <li class="nav-item" role="presentation">
  46. <a href="#other_settings" class="nav-link" data-bs-toggle="tab" aria-selected="false"
  47. tabindex="-1" role="tab">
  48. <i class="ti ti-settings icon"></i>&nbsp;
  49. 其他
  50. </a>
  51. </li>
  52. </ul>
  53. <div class="card-body">
  54. <div class="tab-content">
  55. <div class="tab-pane active show" id="personal_information" role="tabpanel">
  56. <div class="row row-deck row-cards">
  57. <div class="col-sm-12 col-md-6">
  58. <div class="card">
  59. <div class="card-body">
  60. <h3 class="card-title">登录邮箱</h3>
  61. <p>当前邮箱:<code id="email">{$user->email}</code></p>
  62. <div class="mb-3">
  63. <input id="new-email" type="email" class="form-control"
  64. placeholder="新邮箱"
  65. {if ! $config['enable_change_email']}disabled=""{/if}>
  66. </div>
  67. {if $public_setting['reg_email_verify'] && $config['enable_change_email']}
  68. <div class="mb-3">
  69. <input id="email-code" type="text" class="form-control"
  70. placeholder="验证码">
  71. </div>
  72. {/if}
  73. </div>
  74. <div class="card-footer">
  75. <div class="d-flex">
  76. {if $public_setting['reg_email_verify'] && $config['enable_change_email']}
  77. <button class="btn btn-link"
  78. hx-post="/user/send" hx-swap="none"
  79. hx-vals='js:{ email: document.getElementById("newemail").value }'>
  80. 获取验证码
  81. </button>
  82. <button class="btn btn-primary ms-auto"
  83. hx-post="/user/email" hx-swap="none"
  84. hx-vals='js:{
  85. newemail: document.getElementById("new-email").value,
  86. emailcode: document.getElementById("email-code").value
  87. }'>
  88. 修改
  89. </button>
  90. {elseif $config['enable_change_email']}
  91. <button class="btn btn-primary ms-auto"
  92. hx-post="/user/email" hx-swap="none"
  93. hx-vals='js:{ newemail: document.getElementById("new-email").value }'>
  94. 修改
  95. </button>
  96. {else}
  97. <button class="btn btn-primary ms-auto"
  98. disabled>不允许修改
  99. </button>
  100. {/if}
  101. </div>
  102. </div>
  103. </div>
  104. </div>
  105. <div class="col-sm-12 col-md-6">
  106. <div class="card">
  107. <div class="card-body">
  108. <h3 class="card-title">用戶名</h3>
  109. <p>当前用戶名:<code id="username">{$user->user_name}</code></p>
  110. <div class="mb-3">
  111. <input id="new-username" type="text" class="form-control"
  112. placeholder="新用戶名" autocomplete="off">
  113. </div>
  114. </div>
  115. <div class="card-footer">
  116. <div class="d-flex">
  117. <button class="btn btn-primary ms-auto"
  118. hx-post="/user/username" hx-swap="none"
  119. hx-vals='js:{ newusername: document.getElementById("new-username").value }'>
  120. 修改
  121. </button>
  122. </div>
  123. </div>
  124. </div>
  125. </div>
  126. <div class="col-sm-12 col-md-6">
  127. <div class="card">
  128. <div class="card-body">
  129. <h3 class="card-title">IM 账号绑定</h3>
  130. <div class="mb-3">
  131. <select id="imtype" class="form-select"
  132. {if $user->im_type !== 0 && $user->im_value !== ''}disabled=""{/if}>
  133. <option value="0" {if $user->im_type === 0}selected{/if}>
  134. 未绑定
  135. </option>
  136. <option value="1" {if $user->im_type === 1}selected{/if}>
  137. Slack
  138. </option>
  139. <option value="2" {if $user->im_type === 2}selected{/if}>
  140. Discord
  141. </option>
  142. <option value="4" {if $user->im_type === 4}selected{/if}>
  143. Telegram
  144. </option>
  145. </select>
  146. </div>
  147. <div class="mb-3">
  148. <input id="imvalue" type="text" class="form-control"
  149. disabled="" value="{$user->im_value}">
  150. </div>
  151. </div>
  152. <div class="card-footer">
  153. <div class="d-flex btn-list justify-content-end"
  154. id="oauth-provider"></div>
  155. </div>
  156. </div>
  157. </div>
  158. <div class="col-sm-12 col-md-6">
  159. <div class="card">
  160. <div class="card-body">
  161. <h3 class="card-title">解绑 IM 账户</h3>
  162. {if $user->im_type === 0}
  163. <p>你的账户当前没有绑定任何 IM 服务</p>
  164. {else}
  165. <p>
  166. 当前绑定的 IM 服务:{$user->imType()}
  167. <br>
  168. 账户 ID:<code>{$user->im_value}</code>
  169. </p>
  170. {/if}
  171. </div>
  172. {if $user->im_type !== 0}
  173. <div class="card-footer">
  174. <div class="d-flex">
  175. <button class="btn btn-red ms-auto"
  176. hx-post="/user/unbind_im" hx-swap="none">
  177. 解绑
  178. </button>
  179. </div>
  180. </div>
  181. {/if}
  182. </div>
  183. </div>
  184. </div>
  185. </div>
  186. <div class="tab-pane" id="login_security" role="tabpanel">
  187. <div class="row row-deck row-cards">
  188. <div class="col-sm-12 col-md-6">
  189. <div class="card">
  190. <div class="card-body">
  191. <h3 class="card-title">多因素认证</h3>
  192. <div class="col-md-12">
  193. <div class="col-sm-6 col-md-6">
  194. <i class="ti ti-brand-apple"></i>
  195. <a target="view_window"
  196. href="https://apps.apple.com/us/app/google-authenticator/id388497605">iOS
  197. 客户端
  198. </a>
  199. &nbsp;&nbsp;&nbsp;
  200. <i class="ti ti-brand-android"></i>
  201. <a target="view_window"
  202. href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Android
  203. 客户端
  204. </a>
  205. </div>
  206. </div>
  207. <br>
  208. <div class="row">
  209. <div class="col-md-3">
  210. <p id="qrcode"></p>
  211. </div>
  212. <div class="col-md-9">
  213. <div class="mb-3">
  214. <select id="ga-enable" class="form-select">
  215. <option value="0">不使用</option>
  216. <option value="1"
  217. {if $user->ga_enable === '1'}selected{/if}>
  218. 使用两步认证登录
  219. </option>
  220. </select>
  221. </div>
  222. <div class="mb-3">
  223. <input id="ga-test-code" type="text"
  224. class="form-control"
  225. placeholder="测试两步认证验证码">
  226. </div>
  227. <div class="col-md-12">
  228. <p>密钥:
  229. <code id="ga-token">
  230. {$user->ga_token}
  231. </code>
  232. </p>
  233. </div>
  234. </div>
  235. </div>
  236. </div>
  237. <div class="card-footer">
  238. <div class="d-flex">
  239. <button class="btn btn-link"
  240. hx-post="/user/ga_reset" hx-swap="none" >
  241. 重置
  242. </button>
  243. <button class="btn btn-link"
  244. hx-post="/user/ga_check" hx-swap="none"
  245. hx-vals='js:{ code: document.getElementById("ga-test-code").value }'>
  246. 测试
  247. </button>
  248. <button class="btn btn-primary ms-auto"
  249. hx-post="/user/ga_set" hx-swap="none"
  250. hx-vals='js:{ enable: document.getElementById("ga-enable").value }'>
  251. 设置
  252. </button>
  253. </div>
  254. </div>
  255. </div>
  256. </div>
  257. <div class="col-sm-12 col-md-6">
  258. <div class="card">
  259. <div class="card-body">
  260. <h3 class="card-title">修改登录密码</h3>
  261. <div class="mb-3">
  262. <form>
  263. <input id="password" type="password" class="form-control"
  264. placeholder="当前登录密码" autocomplete="off">
  265. </form>
  266. </div>
  267. <div class="mb-3">
  268. <form>
  269. <input id="new_password" type="password"
  270. class="form-control" placeholder="输入新密码"
  271. autocomplete="off">
  272. </form>
  273. </div>
  274. <div class="mb-3">
  275. <form>
  276. <input id="confirm_new_password" type="password"
  277. class="form-control" placeholder="再次输入新密码"
  278. autocomplete="off">
  279. </form>
  280. </div>
  281. </div>
  282. <div class="card-footer">
  283. <div class="d-flex">
  284. <button class="btn btn-primary ms-auto"
  285. hx-post="/user/password" hx-swap="none"
  286. hx-vals='js:{
  287. new_password: document.getElementById("new_password").value,
  288. confirm_new_password: document.getElementById("confirm_new_password").value,
  289. password: document.getElementById("password").value
  290. }'>
  291. 修改
  292. </button>
  293. </div>
  294. </div>
  295. </div>
  296. </div>
  297. </div>
  298. </div>
  299. <div class="tab-pane" id="use_safety" role="tabpanel">
  300. <div class="row row-deck row-cards">
  301. <div class="col-sm-12 col-md-6">
  302. <div class="card">
  303. <div class="card-body">
  304. <h3 class="card-title">更换加密方式</h3>
  305. <p>
  306. 不同的客户端支持的加密方式可能会有所不同,请参考客户端支持列表进行设置</p>
  307. <div class="mb-3">
  308. <select id="user-method" class="form-select">
  309. {foreach $methods as $method}
  310. <option value="{$method}"
  311. {if $user->method === $method}selected{/if}>
  312. {$method}
  313. </option>
  314. {/foreach}
  315. </select>
  316. </div>
  317. </div>
  318. <div class="card-footer">
  319. <div class="d-flex">
  320. <button class="btn btn-primary ms-auto"
  321. hx-post="/user/method" hx-swap="none"
  322. hx-vals='js:{ method: document.getElementById("user-method").value }'>
  323. 修改
  324. </button>
  325. </div>
  326. </div>
  327. </div>
  328. </div>
  329. <div class="col-sm-12 col-md-6">
  330. <div class="card">
  331. <div class="card-body">
  332. <h3 class="card-title">重置订阅地址</h3>
  333. <p>重置订阅地址后,旧的订阅地址将无法获取配置,但节点配置仍能使用。
  334. 如果希望作废旧节点配置请配合重置连接密码操作</p>
  335. </div>
  336. <div class="card-footer">
  337. <div class="d-flex">
  338. <button class="btn btn-primary ms-auto bg-red"
  339. hx-post="/user/url_reset" hx-swap="none">
  340. 重置
  341. </button>
  342. </div>
  343. </div>
  344. </div>
  345. </div>
  346. <div class="col-sm-12 col-md-6">
  347. <div class="card">
  348. <div class="card-body">
  349. <h3 class="card-title">重置连接密码</h3>
  350. <p>重置连接密码与UUID ,重置后需更新订阅,才能继续使用</p>
  351. <p>当前连接密码:<code id="passwd">{$user->passwd}</code></p>
  352. <p>当前UUID:<code id="uuid">{$user->uuid}</code></p>
  353. </div>
  354. <div class="card-footer">
  355. <div class="d-flex">
  356. <button class="btn btn-primary ms-auto bg-red"
  357. hx-post="/user/passwd_reset" hx-swap="none">
  358. 重置
  359. </button>
  360. </div>
  361. </div>
  362. </div>
  363. </div>
  364. </div>
  365. </div>
  366. <div class="tab-pane" id="other_settings" role="tabpanel">
  367. <div class="row row-deck row-cards">
  368. <div class="col-sm-12 col-md-6">
  369. <div class="card">
  370. <div class="card-body">
  371. <h3 class="card-title">每日流量报告</h3>
  372. <div class="mb-3">
  373. <select id="daily-mail" class="form-select">
  374. <option value="0"
  375. {if $user->daily_mail_enable === 0}selected{/if}>
  376. 不接收
  377. </option>
  378. <option value="1"
  379. {if $user->daily_mail_enable === 1}selected{/if}>
  380. 邮件接收
  381. </option>
  382. <option value="2"
  383. {if $user->daily_mail_enable === 2}selected{/if}>
  384. IM 接收
  385. </option>
  386. </select>
  387. </div>
  388. </div>
  389. <div class="card-footer">
  390. <div class="d-flex">
  391. <button class="btn btn-primary ms-auto"
  392. hx-post="/user/daily_mail" hx-swap="none"
  393. hx-vals='js:{ mail: document.getElementById("daily-mail").value }'>
  394. 修改
  395. </button>
  396. </div>
  397. </div>
  398. </div>
  399. </div>
  400. <div class="col-sm-12 col-md-6">
  401. <div class="card">
  402. <div class="card-body">
  403. <h3 class="card-title">偏好的联系方式</h3>
  404. <p>当 IM 未绑定时站点依然会向账户邮箱发送通知信息</p>
  405. <div class="mb-3">
  406. <select id="contact-method" class="form-select">
  407. <option value="1"
  408. {if $user->contact_method === 1}selected{/if}>
  409. 邮件
  410. </option>
  411. <option value="2"
  412. {if $user->contact_method === 2}selected{/if}>
  413. IM
  414. </option>
  415. </select>
  416. </div>
  417. </div>
  418. <div class="card-footer">
  419. <div class="d-flex">
  420. <button class="btn btn-primary ms-auto"
  421. hx-post="/user/contact_method" hx-swap="none"
  422. hx-vals='js:{ contact: document.getElementById("contact-method").value }'>
  423. 修改
  424. </button>
  425. </div>
  426. </div>
  427. </div>
  428. </div>
  429. <div class="col-sm-12 col-md-6">
  430. <div class="card">
  431. <div class="card-body">
  432. <h3 class="card-title">修改主题</h3>
  433. <div class="mb-3">
  434. <select id="user-theme" class="form-select">
  435. {foreach $themes as $theme}
  436. <option value="{$theme}"
  437. {if $user->theme === $theme}selected{/if}>{$theme}
  438. </option>
  439. {/foreach}
  440. </select>
  441. </div>
  442. </div>
  443. <div class="card-footer">
  444. <div class="d-flex">
  445. <button class="btn btn-primary ms-auto"
  446. hx-post="/user/theme" hx-swap="none"
  447. hx-vals='js:{ theme: document.getElementById("user-theme").value }'>
  448. 修改
  449. </button>
  450. </div>
  451. </div>
  452. </div>
  453. </div>
  454. {if $config['enable_kill']}
  455. <div class="col-sm-12 col-md-6">
  456. <div class="card">
  457. <div class="card-stamp">
  458. <div class="card-stamp-icon bg-red">
  459. <i class="ti ti-circle-x"></i>
  460. </div>
  461. </div>
  462. <div class="card-body">
  463. <h3 class="card-title">删除账户数据</h3>
  464. </div>
  465. <div class="card-footer">
  466. <button class="btn btn-red" data-bs-toggle="modal"
  467. data-bs-target="#destroy-account">
  468. <i class="ti ti-trash icon"></i>
  469. 确认删除
  470. </button>
  471. </div>
  472. </div>
  473. </div>
  474. {/if}
  475. </div>
  476. </div>
  477. </div>
  478. </div>
  479. </div>
  480. </div>
  481. </div>
  482. </div>
  483. </div>
  484. {if $config['enable_kill']}
  485. <div class="modal modal-blur fade" id="destroy-account" tabindex="-1" role="dialog" aria-hidden="true">
  486. <div class="modal-dialog modal-sm modal-dialog-centered" role="document">
  487. <div class="modal-content">
  488. <button class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
  489. <div class="modal-status bg-danger"></div>
  490. <div class="modal-body text-center py-4">
  491. <i class="ti ti-alert-circle icon mb-2 text-danger icon-lg" style="font-size:3.5rem;"></i>
  492. <h3>删除确认</h3>
  493. <div class="text-secondary">
  494. 请确认是否真的要删除你的账户,此操作无法撤销,你的所有账户数据将会被从服务器上彻底删除
  495. </div>
  496. <div class="py-3">
  497. <form>
  498. <input id="confirm_kill_password" type="password" class="form-control"
  499. placeholder="输入登录密码" autocomplete="off">
  500. </form>
  501. </div>
  502. </div>
  503. <div class="modal-footer">
  504. <div class="w-100">
  505. <div class="row">
  506. <div class="col">
  507. <button class="btn w-100" data-bs-dismiss="modal">
  508. 取消
  509. </button>
  510. </div>
  511. <div class="col">
  512. <button href="#" class="btn btn-danger w-100" data-bs-dismiss="modal"
  513. hx-post="/user/kill" hx-swap="none"
  514. hx-vals='js:{ password: document.getElementById("confirm_kill_password").value }'>
  515. 确认
  516. </button>
  517. </div>
  518. </div>
  519. </div>
  520. </div>
  521. </div>
  522. </div>
  523. </div>
  524. {/if}
  525. <script>
  526. let qrcode = new QRCode('qrcode', {
  527. text: "{$ga_url}",
  528. width: 128,
  529. height: 128,
  530. colorDark: '#000000',
  531. colorLight: '#ffffff',
  532. correctLevel: QRCode.CorrectLevel.H
  533. });
  534. {if $user->im_type === 0 && $user->im_value === ''}
  535. let oauthProvider = $('#oauth-provider');
  536. $("#imtype").on('change', function () {
  537. if ($(this).val() === '0') {
  538. oauthProvider.empty();
  539. } else if ($(this).val() === '1') {
  540. oauthProvider.empty();
  541. oauthProvider.append(
  542. "<a id='bind-slack' class='btn btn-azure ms-auto'>绑定 Slack</a>"
  543. );
  544. } else if ($(this).val() === '2') {
  545. oauthProvider.empty();
  546. oauthProvider.append(
  547. "<a id='bind-discord' class='btn btn-indigo ms-auto'>绑定 Discord</a>"
  548. );
  549. } else if ($(this).val() === '4') {
  550. oauthProvider.empty();
  551. oauthProvider.append(
  552. '<script async src=\"https://telegram.org/js/telegram-widget.js?22\"' +
  553. ' data-telegram-login=\"' + "{$public_setting['telegram_bot']}" +
  554. '\" data-size=\"large" data-onauth=\"onTelegramAuth(user)\"' +
  555. ' data-request-access=\"write\"><\/script>'
  556. );
  557. }
  558. });
  559. oauthProvider.on('click', '#bind-slack', function () {
  560. $.ajax({
  561. type: "POST",
  562. url: "/oauth/slack",
  563. dataType: "json",
  564. success: function (data) {
  565. handleOauthResult(data, 'slack')
  566. }
  567. })
  568. });
  569. oauthProvider.on('click', '#bind-discord', function () {
  570. $.ajax({
  571. type: "POST",
  572. url: "/oauth/discord",
  573. dataType: "json",
  574. success: function (data) {
  575. handleOauthResult(data, 'discord')
  576. }
  577. })
  578. });
  579. function onTelegramAuth(user) {
  580. $.ajax({
  581. type: "POST",
  582. url: "/oauth/telegram",
  583. dataType: "json",
  584. data: {
  585. user: JSON.stringify(user),
  586. },
  587. success: function (data) {
  588. handleOauthResult(data, 'telegram')
  589. }
  590. })
  591. }
  592. function handleOauthResult(data, type = 'telegram') {
  593. if (data.ret === 1) {
  594. if (type === 'telegram') {
  595. $('#success-message').text(data.msg);
  596. $('#success-dialog').modal('show');
  597. } else {
  598. window.location.replace(data.redir);
  599. }
  600. } else {
  601. $('#error-message').text(data.msg);
  602. $('#fail-dialog').modal('show');
  603. }
  604. }
  605. {/if}
  606. </script>
  607. {include file='user/footer.tpl'}