external-accounts.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. {% extends '../layout/2column.html' %}
  2. {% block html_title %}{{ t('Password Settings') }} · {{ path }}{% endblock %}
  3. {% block content_head %}
  4. <div class="header-wrap">
  5. <header id="page-header">
  6. <h1 class="title" id="">{{ t('User Settings') }}</h1>
  7. </header>
  8. </div>
  9. {% endblock %}
  10. {% block content_main %}
  11. <div class="content-main">
  12. <ul class="nav nav-tabs">
  13. <li><a href="/me"><i class="fa fa-gears"></i> {{ t('User Information') }}</a></li>
  14. <li class="active"><a href="/me/external-accounts"><i class="fa fa-user-plus"></i> {{ t('External Accounts') }}</a></li>
  15. <li><a href="/me/password"><i class="fa fa-key"></i> {{ t('Password Settings') }}</a></li>
  16. <li><a href="/me/apiToken"><i class="fa fa-rocket"></i> {{ t('API Settings') }}</a></li>
  17. </ul>
  18. <div class="tab-content">
  19. {% set couldntDisassociateError = req.flash('couldntDisassociateError') %}
  20. {% if couldntDisassociateError != null %}
  21. <div class="alert alert-danger">
  22. <b>Couldn't disassociate External Account</b><br>
  23. You have not set a password and have only one External Account.
  24. </div>
  25. {% endif %}
  26. {% set error = req.flash('errorMessage') %}
  27. {% if error.length %}
  28. {% for e in error %}
  29. <div class="alert alert-danger">
  30. <b>Server Error occured:</b><br>
  31. {{ e }}
  32. </div>
  33. {% endfor %}
  34. {% endif %}
  35. {% set warn = req.flash('warningMessage') %}
  36. {% if warn.length %}
  37. {% for w in warn %}
  38. <div class="alert alert-warning">
  39. {{ w }}
  40. </div>
  41. {% endfor %}
  42. {% endif %}
  43. {% set message = req.flash('successMessage') %}
  44. {% if message.length %}
  45. <div class="alert alert-success">
  46. <b>{{ message }}</b>
  47. </div>
  48. {% endif %}
  49. <legend style="line-height: 1.7em;">
  50. <button class="btn btn-default btn-sm pull-right" data-target="#create-external-account" data-toggle="modal">
  51. <i class="fa fa-plus-circle" aria-hidden="true"></i>
  52. Add
  53. </button>
  54. {{ t('External Accounts') }}
  55. </legend>
  56. <div class="row">
  57. <div class="col-md-12">
  58. <table class="table table-hover table-striped table-bordered table-user-list">
  59. <thead>
  60. <tr>
  61. <th width="120px">Authentication Provider</th>
  62. <th>
  63. <code>accountId</code>
  64. </th>
  65. <th width="200px">{{ t('Created') }}</th>
  66. <th width="150px">{{ t('Admin') }}</th>
  67. </tr>
  68. </thead>
  69. <tbody>
  70. {% for account in externalAccounts %}
  71. <tr>
  72. <td>{{ account.providerType }}</td>
  73. <td>
  74. <strong>{{ account.accountId }}</strong>
  75. </td>
  76. <td>{{ account.createdAt|date('Y-m-d', account.createdAt.getTimezoneOffset()) }}</td>
  77. <td class="text-center">
  78. <button class="btn btn-default btn-sm btn-danger"
  79. data-toggle="modal" data-target="#diassociate-external-account" data-provider-type="{{ account.providerType }}" data-account-id="{{ account.accountId }}">
  80. <i class="fa fa-unlink"></i>
  81. {{ t('Diassociate') }}
  82. </button>
  83. </td>
  84. </tr>
  85. {% endfor %}
  86. </tbody>
  87. </table>
  88. </div>
  89. </div>
  90. {# modal #}
  91. <style>
  92. .modal.create-external-account .modal-dialog {
  93. width: 750px;
  94. }
  95. </style>
  96. <div class="modal create-external-account" id="create-external-account">
  97. <div class="modal-dialog">
  98. <div class="modal-content">
  99. <div class="modal-header">
  100. <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
  101. <h4 class="modal-title">{{ t('Create External Account') }}</h4>
  102. </div>
  103. <div class="modal-body">
  104. <ul class="nav nav-tabs passport-settings" role="tablist">
  105. <li class="active">
  106. <a href="#passport-ldap" data-toggle="tab" role="tab"><i class="fa fa-sitemap"></i> LDAP</a>
  107. </li>
  108. <li>
  109. <a href="#passport-google-oauth" data-toggle="tab" role="tab"><i class="fa fa-google"></i> Google OAuth</a>
  110. </li>
  111. <li>
  112. <a href="#passport-facebook" data-toggle="tab" role="tab"><i class="fa fa-facebook"></i> Facebook</a>
  113. </li>
  114. <li>
  115. <a href="#passport-twitter" data-toggle="tab" role="tab"><i class="fa fa-twitter"></i> Twitter</a>
  116. </li>
  117. <li>
  118. <a href="#passport-github" data-toggle="tab" role="tab"><i class="fa fa-github"></i> Github</a>
  119. </li>
  120. </ul>
  121. <div class="tab-content passport-settings">
  122. <div id="passport-ldap" class="tab-pane active" role="tabpanel" >
  123. <div id="form-box">
  124. <form id="formLdapAssociation" method="post" class="form-horizontal" role="form">
  125. <div class="alert-container"></div>
  126. <fieldset>
  127. <div class="form-group">
  128. <label for="username" class="col-xs-3 control-label">{{ t('Username') }}</label>
  129. <div class="col-xs-6">
  130. <input class="form-control" name="loginForm[username]">
  131. </div>
  132. </div>
  133. <div class="form-group">
  134. <label for="password" class="col-xs-3 control-label">{{ t('Password') }}</label>
  135. <div class="col-xs-6">
  136. <input class="form-control col-xs-4" type="password" name="loginForm[password]">
  137. </div>
  138. </div>
  139. <div class="form-group">
  140. <div class="col-xs-12 text-right">
  141. <button type="button" class="btn btn-default" onclick="testAssociateLdap()">{{ t('Test') }}</button>
  142. <button type="button" class="btn btn-primary" onclick="associateLdap()">{{ t('Add') }}</button>
  143. </div>
  144. </div>
  145. </fieldset>
  146. </form>
  147. </div>
  148. </div>
  149. <div id="passport-google-oauth" class="tab-pane" role="tabpanel">
  150. (TBD)
  151. </div>
  152. <div id="passport-facebook" class="tab-pane" role="tabpanel">
  153. (TBD)
  154. </div>
  155. <div id="passport-twitter" class="tab-pane" role="tabpanel">
  156. (TBD)
  157. </div>
  158. <div id="passport-github" class="tab-pane" role="tabpanel">
  159. (TBD)
  160. </div>
  161. </div><!-- /.tab-content -->
  162. </div><!-- /.modal-body -->
  163. </div><!-- /.modal-content -->
  164. </div><!-- /.modal-dialog -->
  165. <script>
  166. /**
  167. * associate (submit the form)
  168. */
  169. function associateLdap() {
  170. var $form = $('#formLdapAssociation');
  171. var $action = '/me/external-accounts/associateLdap';
  172. $form.attr('action', $action);
  173. $form.submit();
  174. }
  175. /**
  176. * test association (ajax)
  177. */
  178. function testAssociateLdap() {
  179. function showMessage(formId, msg, status) {
  180. $('#' + formId + ' .alert-container .alert').remove();
  181. var $message = $('<p class="alert"></p>');
  182. $message.addClass('alert-' + status);
  183. $message.html(msg.replace('\n', '<br>'));
  184. $message.appendTo('#' + formId + '> .alert-container');
  185. if (status == 'success') {
  186. setTimeout(function()
  187. {
  188. $message.fadeOut({
  189. complete: function() {
  190. $message.remove();
  191. }
  192. });
  193. }, 5000);
  194. }
  195. }
  196. var $form = $('#formLdapAssociation');
  197. var $action = '/_api/me/external-accounts/testAssociateLdap';
  198. var $id = $form.attr('id');
  199. var $button = $('button', this);
  200. $button.attr('disabled', 'disabled');
  201. var jqxhr = $.post($action, $form.serialize(), function(data)
  202. {
  203. if (!data.status) {
  204. showMessage($id, 'data.status not found', 'danger');
  205. }
  206. else {
  207. showMessage($id, data.message, data.status);
  208. }
  209. })
  210. .fail(function() {
  211. showMessage($id, 'エラーが発生しました', 'danger');
  212. })
  213. .always(function() {
  214. $button.prop('disabled', false);
  215. });
  216. return false;
  217. }
  218. </script>
  219. </div><!-- /.modal -->
  220. <div class="modal diassociate-external-account" id="diassociate-external-account">
  221. <div class="modal-dialog">
  222. <div class="modal-content">
  223. <div class="modal-header">
  224. <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
  225. <h4 class="modal-title">{{ t('Diassociate External Account') }}</h4>
  226. </div>
  227. <div class="modal-body">
  228. <div class="row">
  229. <div class="col-md-12">
  230. <p><b>
  231. Are you sure to diassociate the
  232. <span class="diassociate-provider-type"></span> account
  233. <code class="diassociate-account-id"></code>?
  234. </b></p>
  235. </div>
  236. </div>
  237. </div>
  238. <div class="modal-footer">
  239. <form action="/me/external-accounts/disassociate" method="post">
  240. <input type="hidden" name="_csrf" value="{{ csrf() }}">
  241. <input type="hidden" name="providerType">
  242. <input type="hidden" name="accountId">
  243. <button type="button" class="btn btn-sm btn-default" data-dismiss="modal">
  244. {{ t('Cancel') }}
  245. </button>
  246. <button type="submit" class="btn btn-sm btn-danger">
  247. <i class="fa fa-unlink"></i>
  248. {{ t('Diassociate') }}
  249. </button>
  250. </form>
  251. </div>
  252. </div><!-- /.modal-content -->
  253. </div><!-- /.modal-dialog -->
  254. <script>
  255. $('#diassociate-external-account').on('show.bs.modal', function (event) {
  256. var modal = $(this);
  257. var button = $(event.relatedTarget); // Button that triggered the modal
  258. // get data-*
  259. var providerType = button.data('provider-type');
  260. var accountId = button.data('account-id');
  261. // set labels
  262. modal.find('.diassociate-provider-type').text(providerType);
  263. modal.find('.diassociate-account-id').text(accountId);
  264. // set hidden inputs
  265. modal.find('input:hidden[name="providerType"]').val(providerType);
  266. modal.find('input:hidden[name="accountId"]').val(accountId);
  267. })
  268. </script>
  269. </div><!-- /.modal -->
  270. </div>
  271. {% endblock content_main %}
  272. {% block content_footer %}
  273. {% endblock %}
  274. {% block footer %}
  275. {% endblock %}