summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authortamaina <tamaina@hotmail.co.jp>2023-02-09 17:18:27 +0000
committertamaina <tamaina@hotmail.co.jp>2023-02-09 17:18:27 +0000
commitca0d53ec5df747bbfba583f161a38af9dfe4d96c (patch)
treecdb58f49bad40367bcea77db041250d577b5cc3d /packages
parentchore: determine dimensions of the helix of cat ears based on the size of ava... (diff)
downloadmisskey-ca0d53ec5df747bbfba583f161a38af9dfe4d96c.tar.gz
misskey-ca0d53ec5df747bbfba583f161a38af9dfe4d96c.tar.bz2
misskey-ca0d53ec5df747bbfba583f161a38af9dfe4d96c.zip
enhance(client): /authおよびMiAuthのUIをブラッシュアップ
Fix #9742
Diffstat (limited to 'packages')
-rw-r--r--packages/frontend/src/pages/auth.form.vue108
-rw-r--r--packages/frontend/src/pages/auth.vue170
-rw-r--r--packages/frontend/src/pages/miauth.vue78
3 files changed, 196 insertions, 160 deletions
diff --git a/packages/frontend/src/pages/auth.form.vue b/packages/frontend/src/pages/auth.form.vue
index 801295fce9..1a1cd55eee 100644
--- a/packages/frontend/src/pages/auth.form.vue
+++ b/packages/frontend/src/pages/auth.form.vue
@@ -1,60 +1,66 @@
<template>
-<section class="">
- <div class="">{{ $t('_auth.shareAccess', { name: app.name }) }}</div>
- <div class="">
- <h2>{{ app.name }}</h2>
- <p class="id">{{ app.id }}</p>
- <p class="description">{{ app.description }}</p>
- </div>
- <div class="">
- <h2>{{ $ts._auth.permissionAsk }}</h2>
- <ul>
- <li v-for="p in app.permission" :key="p">{{ $t(`_permissions.${p}`) }}</li>
- </ul>
- </div>
- <div class="">
- <MkButton inline @click="cancel">{{ $ts.cancel }}</MkButton>
- <MkButton inline primary @click="accept">{{ $ts.accept }}</MkButton>
- </div>
-</section>
+ <section>
+ <div v-if="app.permission.length > 0">
+ <p>{{ i18n.ts._auth.permissionAsk }}</p>
+ <ul>
+ <li v-for="p in app.permission" :key="p">{{ $t(`_permissions.${p}`) }}</li>
+ </ul>
+ </div>
+ <div>{{ i18n.t('_auth.shareAccess', { name: `${name} (${app.id})` }) }}</div>
+ <div :class="$style.buttons">
+ <MkButton inline @click="cancel">{{ i18n.ts.cancel }}</MkButton>
+ <MkButton inline primary @click="accept">{{ i18n.ts.accept }}</MkButton>
+ </div>
+ </section>
</template>
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { } from 'vue';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os';
+import { i18n } from '@/i18n';
+import { AuthSession } from 'misskey-js/built/entities';
-export default defineComponent({
- components: {
- MkButton,
- },
- props: ['session'],
- computed: {
- name(): string {
- const el = document.createElement('div');
- el.textContent = this.app.name;
- return el.innerHTML;
- },
- app(): any {
- return this.session.app;
- },
- },
- methods: {
- cancel() {
- os.api('auth/deny', {
- token: this.session.token,
- }).then(() => {
- this.$emit('denied');
- });
- },
+const props = defineProps<{
+ session: AuthSession;
+}>();
- accept() {
- os.api('auth/accept', {
- token: this.session.token,
- }).then(() => {
- this.$emit('accepted');
- });
- },
- },
+const emit = defineEmits<{
+ (event: 'accepted'): void;
+ (event: 'denied'): void;
+}>();
+
+const app = $computed(() => props.session.app);
+
+const name = $computed(() => {
+ const el = document.createElement('div');
+ el.textContent = app.name;
+ return el.innerHTML;
});
+
+function cancel() {
+ os.api('auth/deny', {
+ token: props.session.token,
+ }).then(() => {
+ emit('denied');
+ });
+}
+
+function accept() {
+ os.api('auth/accept', {
+ token: props.session.token,
+ }).then(() => {
+ emit('accepted');
+ });
+}
+
</script>
+
+<style lang="scss" module>
+.buttons {
+ margin-top: 16px;
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+</style>
diff --git a/packages/frontend/src/pages/auth.vue b/packages/frontend/src/pages/auth.vue
index b7727ca30d..50afffc460 100644
--- a/packages/frontend/src/pages/auth.vue
+++ b/packages/frontend/src/pages/auth.vue
@@ -1,93 +1,105 @@
<template>
-<div v-if="$i && fetching" class="">
- <MkLoading/>
-</div>
-<div v-else-if="$i">
- <XForm
- v-if="state == 'waiting'"
- ref="form"
- class="form"
- :session="session"
- @denied="state = 'denied'"
- @accepted="accepted"
- />
- <div v-if="state == 'denied'" class="denied">
- <h1>{{ $ts._auth.denied }}</h1>
- </div>
- <div v-if="state == 'accepted'" class="accepted">
- <h1>{{ session.app.isAuthorized ? $t('already-authorized') : $ts.allowed }}</h1>
- <p v-if="session.app.callbackUrl">{{ $ts._auth.callback }}<MkEllipsis/></p>
- <p v-if="!session.app.callbackUrl">{{ $ts._auth.pleaseGoBack }}</p>
- </div>
- <div v-if="state == 'fetch-session-error'" class="error">
- <p>{{ $ts.somethingHappened }}</p>
- </div>
-</div>
-<div v-else class="signin">
- <MkSignin @login="onLogin"/>
-</div>
+<MkStickyContainer>
+ <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs" /></template>
+ <MkSpacer :content-max="500">
+ <div v-if="state == 'fetch-session-error'">
+ <p>{{ i18n.ts.somethingHappened }}</p>
+ </div>
+ <div v-else-if="$i && !session">
+ <MkLoading />
+ </div>
+ <div v-else-if="$i && session">
+ <XForm
+ v-if="state == 'waiting'"
+ class="form"
+ :session="session"
+ @denied="state = 'denied'"
+ @accepted="accepted"
+ />
+ <div v-if="state == 'denied'">
+ <h1>{{ i18n.ts._auth.denied }}</h1>
+ </div>
+ <div v-if="state == 'accepted' && session">
+ <h1>{{ session.app.isAuthorized ? $t('already-authorized') : i18n.ts.allowed }}</h1>
+ <p v-if="session.app.callbackUrl">{{ i18n.ts._auth.callback }}
+ <MkEllipsis />
+ </p>
+ <p v-if="!session.app.callbackUrl">{{ i18n.ts._auth.pleaseGoBack }}</p>
+ </div>
+ </div>
+ <div v-else>
+ <p :class="$style.loginMessage">{{ i18n.ts._auth.pleaseLogin }}</p>
+ <MkSignin @login="onLogin" />
+ </div>
+ </MkSpacer>
+</MkStickyContainer>
</template>
-<script lang="ts">
-import { defineComponent } from 'vue';
+<script lang="ts" setup>
+import { onMounted } from 'vue';
import XForm from './auth.form.vue';
import MkSignin from '@/components/MkSignin.vue';
import * as os from '@/os';
-import { login } from '@/account';
+import { $i, login } from '@/account';
+import { definePageMetadata } from '@/scripts/page-metadata';
+import { AuthSession } from 'misskey-js/built/entities';
+import { i18n } from '@/i18n';
-export default defineComponent({
- components: {
- XForm,
- MkSignin,
- },
- props: ['token'],
- data() {
- return {
- state: null,
- session: null,
- fetching: true,
- };
- },
- mounted() {
- if (!this.$i) return;
+const props = defineProps<{
+ token: string;
+}>();
- // Fetch session
- os.api('auth/session/show', {
- token: this.token,
- }).then(session => {
- this.session = session;
- this.fetching = false;
+let state = $ref<'waiting' | 'accepted' | 'fetch-session-error' | 'denied' | null>(null);
+let session = $ref<AuthSession | null>(null);
- // 既に連携していた場合
- if (this.session.app.isAuthorized) {
- os.api('auth/accept', {
- token: this.session.token,
- }).then(() => {
- this.accepted();
- });
- } else {
- this.state = 'waiting';
- }
- }).catch(error => {
- this.state = 'fetch-session-error';
- this.fetching = false;
+function accepted() {
+ state = 'accepted';
+ if (session && session.app.callbackUrl) {
+ const url = new URL(session.app.callbackUrl);
+ if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url');
+ location.href = `${session.app.callbackUrl}?token=${session.token}`;
+ }
+}
+
+function onLogin(res) {
+ login(res.i);
+}
+
+onMounted(async () => {
+ if (!$i) return;
+
+ try {
+ session = await os.api('auth/session/show', {
+ token: props.token,
});
- },
- methods: {
- accepted() {
- this.state = 'accepted';
- if (this.session.app.callbackUrl) {
- const url = new URL(this.session.app.callbackUrl);
- if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url');
- location.href = `${this.session.app.callbackUrl}?token=${this.session.token}`;
- }
- }, onLogin(res) {
- login(res.i);
- },
- },
+
+ // 既に連携していた場合
+ if (session.app.isAuthorized) {
+ await os.api('auth/accept', {
+ token: session.token,
+ });
+ accepted();
+ } else {
+ state = 'waiting';
+ }
+ } catch (e) {
+ state = 'fetch-session-error';
+ }
});
-</script>
-<style lang="scss" scoped>
+const headerActions = $computed(() => []);
+
+const headerTabs = $computed(() => []);
+
+definePageMetadata({
+ title: i18n.ts._auth.shareAccessTitle,
+ icon: 'ti ti-apps',
+});
+</script>
+<style lang="scss" module>
+.loginMessage {
+ text-align: center;
+ margin: 8px 0 24px;
+}
</style>
diff --git a/packages/frontend/src/pages/miauth.vue b/packages/frontend/src/pages/miauth.vue
index 9a4019e5b1..0a82ef8e44 100644
--- a/packages/frontend/src/pages/miauth.vue
+++ b/packages/frontend/src/pages/miauth.vue
@@ -1,41 +1,39 @@
<template>
-<MkSpacer :content-max="800">
- <div v-if="$i">
- <div v-if="state == 'waiting'" class="waiting">
- <div class="">
+<MkStickyContainer>
+ <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs" /></template>
+ <MkSpacer :content-max="800">
+ <div v-if="$i">
+ <div v-if="state == 'waiting'">
<MkLoading/>
</div>
- </div>
- <div v-if="state == 'denied'" class="denied">
- <div class="">
+ <div v-if="state == 'denied'">
<p>{{ i18n.ts._auth.denied }}</p>
</div>
- </div>
- <div v-else-if="state == 'accepted'" class="accepted">
- <div class="">
+ <div v-else-if="state == 'accepted'" class="accepted">
<p v-if="callback">{{ i18n.ts._auth.callback }}<MkEllipsis/></p>
<p v-else>{{ i18n.ts._auth.pleaseGoBack }}</p>
</div>
- </div>
- <div v-else class="">
- <div v-if="name" class="">{{ $t('_auth.shareAccess', { name: name }) }}</div>
- <div v-else class="">{{ i18n.ts._auth.shareAccessAsk }}</div>
- <div class="">
- <p>{{ i18n.ts._auth.permissionAsk }}</p>
- <ul>
- <li v-for="p in _permissions" :key="p">{{ $t(`_permissions.${p}`) }}</li>
- </ul>
- </div>
- <div class="">
- <MkButton inline @click="deny">{{ i18n.ts.cancel }}</MkButton>
- <MkButton inline primary @click="accept">{{ i18n.ts.accept }}</MkButton>
+ <div v-else>
+ <div v-if="name">{{ $t('_auth.shareAccess', { name: name }) }}</div>
+ <div v-else>{{ i18n.ts._auth.shareAccessAsk }}</div>
+ <div v-if="_permissions.length > 0">
+ <p>{{ i18n.ts._auth.permissionAsk }}</p>
+ <ul>
+ <li v-for="p in _permissions" :key="p">{{ $t(`_permissions.${p}`) }}</li>
+ </ul>
+ </div>
+ <div :class="$style.buttons">
+ <MkButton inline @click="deny">{{ i18n.ts.cancel }}</MkButton>
+ <MkButton inline primary @click="accept">{{ i18n.ts.accept }}</MkButton>
+ </div>
</div>
</div>
- </div>
- <div v-else class="signin">
- <MkSignin @login="onLogin"/>
- </div>
-</MkSpacer>
+ <div v-else>
+ <p :class="$style.loginMessage">{{ i18n.ts._auth.pleaseLogin }}</p>
+ <MkSignin @login="onLogin"/>
+ </div>
+ </MkSpacer>
+</MkStickyContainer>
</template>
<script lang="ts" setup>
@@ -45,6 +43,7 @@ import MkButton from '@/components/MkButton.vue';
import * as os from '@/os';
import { $i, login } from '@/account';
import { i18n } from '@/i18n';
+import { definePageMetadata } from '@/scripts/page-metadata';
const props = defineProps<{
session: string;
@@ -54,7 +53,7 @@ const props = defineProps<{
permission: string; // コンマ区切り
}>();
-const _permissions = props.permission.split(',');
+const _permissions = props.permission ? props.permission.split(',') : [];
let state = $ref<string | null>(null);
@@ -83,8 +82,27 @@ function deny(): void {
function onLogin(res): void {
login(res.i);
}
+
+const headerActions = $computed(() => []);
+
+const headerTabs = $computed(() => []);
+
+definePageMetadata({
+ title: 'MiAuth',
+ icon: 'ti ti-apps',
+});
</script>
-<style lang="scss" scoped>
+<style lang="scss" module>
+.buttons {
+ margin-top: 16px;
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+.loginMessage {
+ text-align: center;
+ margin: 8px 0 24px;
+}
</style>