mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core&ui: fix #973
This commit is contained in:
4 files changed
+60
-46
No files matched your search
@@ -4,7 +4,7 @@ import moment from 'moment-timezone';
|
|||||||
import type { Context } from '../context';
|
import type { Context } from '../context';
|
||||||
import {
|
import {
|
||||||
CannotDeleteSystemDomainError, DomainJoinAlreadyMemberError, DomainJoinForbiddenError, ForbiddenError,
|
CannotDeleteSystemDomainError, DomainJoinAlreadyMemberError, DomainJoinForbiddenError, ForbiddenError,
|
||||||
InvalidJoinInvitationCodeError, NotFoundError, OnlyOwnerCanDeleteDomainError, PermissionError, RoleAlreadyExistError, ValidationError,
|
InvalidJoinInvitationCodeError, OnlyOwnerCanDeleteDomainError, PermissionError, RoleAlreadyExistError, ValidationError,
|
||||||
} from '../error';
|
} from '../error';
|
||||||
import type { DomainDoc } from '../interface';
|
import type { DomainDoc } from '../interface';
|
||||||
import avatar from '../lib/avatar';
|
import avatar from '../lib/avatar';
|
||||||
@@ -337,7 +337,6 @@ class DomainJoinHandler extends Handler {
|
|||||||
domain.get(target),
|
domain.get(target),
|
||||||
domain.collUser.findOne({ domainId: target, uid: this.user._id }),
|
domain.collUser.findOne({ domainId: target, uid: this.user._id }),
|
||||||
]);
|
]);
|
||||||
if (!dudoc) throw new NotFoundError(target);
|
|
||||||
const assignedRole = this.user.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN)
|
const assignedRole = this.user.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN)
|
||||||
? 'root'
|
? 'root'
|
||||||
: dudoc?.role || 'default';
|
: dudoc?.role || 'default';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
|
|
||||||
// from https://github.com/logos
|
// from https://github.com/logos
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
const icon = '<svg viewBox="0 0 98 96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>';
|
const icon = '<svg viewBox="0 0 98 96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" /></svg>';
|
||||||
|
|
||||||
export default class LoginWithGithubService extends Service {
|
export default class LoginWithGithubService extends Service {
|
||||||
static inject = ['oauth'];
|
static inject = ['oauth'];
|
||||||
|
|||||||
@@ -24,7 +24,12 @@ export default class TelegramService extends Service {
|
|||||||
icon,
|
icon,
|
||||||
canRegister: config.canRegister,
|
canRegister: config.canRegister,
|
||||||
callback: async function callback({ payload }) {
|
callback: async function callback({ payload }) {
|
||||||
const parsed = JSON.parse(payload);
|
let parsed;
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(payload);
|
||||||
|
} catch (e) {
|
||||||
|
throw new ForbiddenError('Invalid payload');
|
||||||
|
}
|
||||||
const hash = parsed.hash;
|
const hash = parsed.hash;
|
||||||
delete parsed.hash;
|
delete parsed.hash;
|
||||||
const dataCheckString = Object.keys(parsed).sort().map((key) => (`${key}=${parsed[key]}`)).join('\n');
|
const dataCheckString = Object.keys(parsed).sort().map((key) => (`${key}=${parsed[key]}`)).join('\n');
|
||||||
|
|||||||
+52
-42
@@ -9,34 +9,31 @@ import {
|
|||||||
delay, i18n, request, secureRandomString, tpl,
|
delay, i18n, request, secureRandomString, tpl,
|
||||||
} from 'vj/utils';
|
} from 'vj/utils';
|
||||||
|
|
||||||
const t = (s) => escape(i18n(s));
|
|
||||||
|
|
||||||
async function changeMail() {
|
async function changeMail() {
|
||||||
const changeMailDialog = new ActionDialog({
|
const changeMailDialog = new ActionDialog({
|
||||||
$body: tpl`
|
$body: tpl(
|
||||||
<div class="typo">
|
<div className="typo" id="change-mail-dialog">
|
||||||
<p>${i18n('Please enter your current password and new email address:')}</p>
|
<label>{i18n('Current Password')}
|
||||||
<label>${i18n('Current Password')}
|
<div className="textbox-container">
|
||||||
<div class="textbox-container">
|
<input className="textbox" type="password" name="password" data-autofocus required></input>
|
||||||
<input class="textbox" type="password" name="password" data-autofocus required></input>
|
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<label>${i18n('Current Email')}
|
<label>{i18n('Current Email')}
|
||||||
<div class="textbox-container">
|
<div className="textbox-container">
|
||||||
<input class="textbox" type="text" name="currentEmail" value="${UserContext.mail}" disabled></input>
|
<input className="textbox" type="text" name="currentEmail" value={UserContext.mail} disabled></input>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<label>${i18n('New Email')}
|
<label>{i18n('New Email')}
|
||||||
<div class="textbox-container">
|
<div className="textbox-container">
|
||||||
<input class="textbox" type="text" name="mail" required></input>
|
<input className="textbox" type="text" name="mail" required></input>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
`,
|
),
|
||||||
onDispatch(action) {
|
onDispatch(action) {
|
||||||
if (action === 'ok') {
|
if (action === 'ok') {
|
||||||
const $password = $('[name="password"]');
|
const $password = $('#change-mail-dialog [name="password"]');
|
||||||
const $mail = $('[name="mail"]');
|
const $mail = $('#change-mail-dialog [name="mail"]');
|
||||||
if (!$password.val() || !$mail.val()) {
|
if (!$password.val() || !$mail.val()) {
|
||||||
if (!$password.val()) $password.focus();
|
if (!$password.val()) $password.focus();
|
||||||
else $mail.focus();
|
else $mail.focus();
|
||||||
@@ -162,35 +159,48 @@ async function enableAuthn(type: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default new NamedPage('home_security', () => {
|
export default new NamedPage('home_security', () => {
|
||||||
const menuLink = (inner: string, action?: string) => `
|
const MenuLink = ({ children, action, icon }: { children: React.ReactNode, action?: string, icon?: string }) => (
|
||||||
<li class="menu__item" ${action ? '' : 'disabled'}>
|
<li className={`menu__item ${action ? '' : 'disabled'}`}>
|
||||||
<a class="menu__link" ${action ? `data-action="${action}"` : 'disabled'}>${inner}</a>
|
<a className={`menu__link ${action ? '' : 'disabled'}`} data-action={action}>
|
||||||
|
{icon && <span className={`icon icon-${icon}`} />}
|
||||||
|
{children}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
`;
|
);
|
||||||
const fingerprint = '<span class="icon icon-fingerprint"></span>';
|
|
||||||
|
|
||||||
$(document).on('click', '[name="auth_enable"]', async () => {
|
$(document).on('click', '[name="auth_enable"]', async () => {
|
||||||
let $body = `
|
const platformAvailable = browserSupportsWebAuthn() && await platformAuthenticatorIsAvailable();
|
||||||
|
const $body = tpl(
|
||||||
<div>
|
<div>
|
||||||
<h3>${t('Choose Authenticator Type')}</h3>
|
<h3>{i18n('Choose Authenticator Type')}</h3>
|
||||||
<ol class="menu">
|
<ol className="menu">
|
||||||
${menuLink(`<span class="icon icon-platform--mobile"></span>${t('Two Factor Authentication')}`, 'tfa')}
|
<MenuLink action="tfa" icon="platform--mobile">
|
||||||
<li class="menu__seperator"></li>
|
{i18n('Two Factor Authentication')}
|
||||||
`;
|
</MenuLink>
|
||||||
if (!window.isSecureContext || !browserSupportsWebAuthn()) {
|
<li className="menu__seperator"></li>
|
||||||
const message = window.isSecureContext
|
{(!window.isSecureContext || !browserSupportsWebAuthn()) ? (
|
||||||
? "Your browser doesn't support WebAuthn."
|
<MenuLink icon="fingerprint">
|
||||||
: 'Webauthn is not available in insecure context.';
|
{window.isSecureContext
|
||||||
$body += menuLink(`${fingerprint}${t(message)}`);
|
? i18n("Your browser doesn't support WebAuthn.")
|
||||||
} else {
|
: i18n('Webauthn is not available in insecure context.')}
|
||||||
if (!await platformAuthenticatorIsAvailable()) {
|
</MenuLink>
|
||||||
$body += menuLink(`${fingerprint}${t("Your browser doesn't support platform authenticator.")}`);
|
) : (<>
|
||||||
} else {
|
{platformAvailable ? (
|
||||||
$body += menuLink(`${fingerprint}${t('Your Device')}`, 'platform');
|
<MenuLink action="platform" icon="fingerprint">
|
||||||
}
|
{i18n('Your Device')}
|
||||||
$body += menuLink(`<span class="icon icon-usb"></span>${t('Multi Platform Authenticator')}`, 'cross-platform');
|
</MenuLink>
|
||||||
}
|
) : (
|
||||||
$body += '</ol></div>';
|
<MenuLink icon="fingerprint">
|
||||||
|
{i18n("Your browser doesn't support platform authenticator.")}
|
||||||
|
</MenuLink>
|
||||||
|
)}
|
||||||
|
<MenuLink action="cross-platform" icon="usb">
|
||||||
|
{i18n('Multi Platform Authenticator')}
|
||||||
|
</MenuLink>
|
||||||
|
</>)}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
const action = await new ActionDialog({ $body, $action: [] }).open();
|
const action = await new ActionDialog({ $body, $action: [] }).open();
|
||||||
if (!action || action === 'cancel') return;
|
if (!action || action === 'cancel') return;
|
||||||
if (action === 'tfa') enableTfa();
|
if (action === 'tfa') enableTfa();
|
||||||
Reference in new issue
Block a user