1
0
mirror of https://github.com/elk-zone/elk synced 2024-11-27 06:18:07 +09:00

fix: key current instance on user server, not user id (#466)

This commit is contained in:
Daniel Roe 2022-12-20 00:16:15 +00:00 committed by GitHub
parent 7484c5c072
commit 9a7c37db24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 22 deletions

View File

@ -1 +1 @@
MOCK_USER='{"user":{"server":"universeodon.com","token":"yZcpj0FmnsEkUvBiXSCb_KQnccl2IU0kx9TfDbcxPJY","vapidKey":"BJwtUVlyCabpMnLI6HOyu-qMfJswxEq_c8pgRymxjTN_vCzMWfGrRHrwNczj9LIokAHtxh6Ziw1Kq7_ERDoriz0=","account":{"id":"109424142224653388","username":"elkdev","acct":"elkdev@universeodon.com","displayName":"Elk Dev Team","locked":false,"bot":false,"discoverable":null,"group":false,"createdAt":"2022-11-28T00:00:00.000Z","note":"","url":"https://universeodon.com/@elkdev","avatar":"https://universeodon.com/avatars/original/missing.png","avatarStatic":"https://universeodon.com/avatars/original/missing.png","header":"https://universeodon.com/headers/original/missing.png","headerStatic":"https://universeodon.com/headers/original/missing.png","followersCount":3,"followingCount":4,"statusesCount":20,"lastStatusAt":"2022-12-13","noindex":false,"source":{"privacy":"public","sensitive":false,"language":null,"note":"","fields":[],"followRequestsCount":0},"emojis":[],"fields":[],"role":{"id":"-99","name":"","permissions":"65536","color":"","highlighted":false}}},"server":{"109424142224653388":{"uri":"universeodon.com","title":"Universeodon","shortDescription":"Be one with the fediverse.","description":"","email":"novae@universeodon.com","version":"4.0.2","urls":{"streamingApi":"wss://universeodon.com"},"stats":{"userCount":57026,"statusCount":283364,"domainCount":11515},"thumbnail":"https://media.universeodon.com/site_uploads/files/000/000/003/@1x/9de6fc1bbd150b05.png","languages":["en"],"registrations":true,"approvalRequired":false,"invitesEnabled":true,"configuration":{"accounts":{"maxFeaturedTags":10},"statuses":{"maxCharacters":500,"maxMediaAttachments":4,"charactersReservedPerUrl":23},"mediaAttachments":{"supportedMimeTypes":["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"],"imageSizeLimit":10485760,"imageMatrixLimit":16777216,"videoSizeLimit":41943040,"videoFrameRateLimit":60,"videoMatrixLimit":2304000},"polls":{"maxOptions":4,"maxCharactersPerOption":50,"minExpiration":300,"maxExpiration":2629746}},"contactAccount":{"id":"109287809647205395","username":"supernovae","acct":"supernovae","displayName":"Supernovae","locked":false,"bot":false,"discoverable":true,"group":false,"createdAt":"2022-11-04T00:00:00.000Z","note":"","url":"https://universeodon.com/@supernovae","avatar":"https://media.universeodon.com/accounts/avatars/109/287/809/647/205/395/original/551eafba585d19e5.jpg","avatarStatic":"https://media.universeodon.com/accounts/avatars/109/287/809/647/205/395/original/551eafba585d19e5.jpg","header":"https://media.universeodon.com/accounts/headers/109/287/809/647/205/395/original/5de388c5945925c5.jpg","headerStatic":"https://media.universeodon.com/accounts/headers/109/287/809/647/205/395/original/5de388c5945925c5.jpg","followersCount":6387,"followingCount":305,"statusesCount":1753,"lastStatusAt":"2022-11-28","noindex":false,"emojis":[],"fields":[]},"rules":[]}}}' MOCK_USER='{"user":{"server":"universeodon.com","token":"yZcpj0FmnsEkUvBiXSCb_KQnccl2IU0kx9TfDbcxPJY","vapidKey":"BJwtUVlyCabpMnLI6HOyu-qMfJswxEq_c8pgRymxjTN_vCzMWfGrRHrwNczj9LIokAHtxh6Ziw1Kq7_ERDoriz0=","account":{"id":"109424142224653388","username":"elkdev","acct":"elkdev@universeodon.com","displayName":"Elk Dev Team","locked":false,"bot":false,"discoverable":null,"group":false,"createdAt":"2022-11-28T00:00:00.000Z","note":"","url":"https://universeodon.com/@elkdev","avatar":"https://universeodon.com/avatars/original/missing.png","avatarStatic":"https://universeodon.com/avatars/original/missing.png","header":"https://universeodon.com/headers/original/missing.png","headerStatic":"https://universeodon.com/headers/original/missing.png","followersCount":3,"followingCount":4,"statusesCount":20,"lastStatusAt":"2022-12-13","noindex":false,"source":{"privacy":"public","sensitive":false,"language":null,"note":"","fields":[],"followRequestsCount":0},"emojis":[],"fields":[],"role":{"id":"-99","name":"","permissions":"65536","color":"","highlighted":false}}},"server":{"universeodon.com":{"uri":"universeodon.com","title":"Universeodon","shortDescription":"Be one with the fediverse.","description":"","email":"novae@universeodon.com","version":"4.0.2","urls":{"streamingApi":"wss://universeodon.com"},"stats":{"userCount":57026,"statusCount":283364,"domainCount":11515},"thumbnail":"https://media.universeodon.com/site_uploads/files/000/000/003/@1x/9de6fc1bbd150b05.png","languages":["en"],"registrations":true,"approvalRequired":false,"invitesEnabled":true,"configuration":{"accounts":{"maxFeaturedTags":10},"statuses":{"maxCharacters":500,"maxMediaAttachments":4,"charactersReservedPerUrl":23},"mediaAttachments":{"supportedMimeTypes":["image/jpeg","image/png","image/gif","image/heic","image/heif","image/webp","image/avif","video/webm","video/mp4","video/quicktime","video/ogg","audio/wave","audio/wav","audio/x-wav","audio/x-pn-wave","audio/vnd.wave","audio/ogg","audio/vorbis","audio/mpeg","audio/mp3","audio/webm","audio/flac","audio/aac","audio/m4a","audio/x-m4a","audio/mp4","audio/3gpp","video/x-ms-asf"],"imageSizeLimit":10485760,"imageMatrixLimit":16777216,"videoSizeLimit":41943040,"videoFrameRateLimit":60,"videoMatrixLimit":2304000},"polls":{"maxOptions":4,"maxCharactersPerOption":50,"minExpiration":300,"maxExpiration":2629746}},"contactAccount":{"id":"109287809647205395","username":"supernovae","acct":"supernovae","displayName":"Supernovae","locked":false,"bot":false,"discoverable":true,"group":false,"createdAt":"2022-11-04T00:00:00.000Z","note":"","url":"https://universeodon.com/@supernovae","avatar":"https://media.universeodon.com/accounts/avatars/109/287/809/647/205/395/original/551eafba585d19e5.jpg","avatarStatic":"https://media.universeodon.com/accounts/avatars/109/287/809/647/205/395/original/551eafba585d19e5.jpg","header":"https://media.universeodon.com/accounts/headers/109/287/809/647/205/395/original/5de388c5945925c5.jpg","headerStatic":"https://media.universeodon.com/accounts/headers/109/287/809/647/205/395/original/5de388c5945925c5.jpg","followersCount":6387,"followingCount":305,"statusesCount":1753,"lastStatusAt":"2022-11-28","noindex":false,"emojis":[],"fields":[]},"rules":[]}}}'

View File

@ -43,7 +43,8 @@ export function getShortHandle({ acct }: Account) {
export function getServerName(account: Account) { export function getServerName(account: Account) {
if (account.acct.includes('@')) if (account.acct.includes('@'))
return account.acct.split('@')[1] return account.acct.split('@')[1]
return account.url.match(UserLinkRE)?.[1] || currentUser.value?.server || '' // We should only lack the server name if we're on the same server as the account
return currentInstance.value?.uri || ''
} }
export function getFullHandle(account: Account) { export function getFullHandle(account: Account) {
@ -64,8 +65,9 @@ export function toShortHandle(fullHandle: string) {
export function getAccountRoute(account: Account) { export function getAccountRoute(account: Account) {
let handle = getFullHandle(account).slice(1) let handle = getFullHandle(account).slice(1)
if (handle.endsWith(`@${currentServer.value}`)) const uri = currentInstance.value?.uri ?? currentServer.value
handle = handle.slice(0, -currentServer.value.length - 1) if (currentInstance.value && handle.endsWith(`@${uri}`))
handle = handle.slice(0, -uri.length - 1)
return useRouter().resolve({ return useRouter().resolve({
name: 'account-index', name: 'account-index',

View File

@ -15,7 +15,7 @@ import type { PushNotificationPolicy, PushNotificationRequest } from '~/composab
const mock = process.mock const mock = process.mock
const users = useLocalStorage<UserLogin[]>(STORAGE_KEY_USERS, mock ? [mock.user] : [], { deep: true }) const users = useLocalStorage<UserLogin[]>(STORAGE_KEY_USERS, mock ? [mock.user] : [], { deep: true })
const servers = useLocalStorage<Record<string, Instance>>(STORAGE_KEY_SERVERS, mock ? mock.server : {}, { deep: true }) const instances = useLocalStorage<Record<string, Instance>>(STORAGE_KEY_SERVERS, mock ? mock.server : {}, { deep: true })
const currentUserId = useLocalStorage<string>(STORAGE_KEY_CURRENT_USER, mock ? mock.user.account.id : '') const currentUserId = useLocalStorage<string>(STORAGE_KEY_CURRENT_USER, mock ? mock.user.account.id : '')
export const currentUser = computed<UserLogin | undefined>(() => { export const currentUser = computed<UserLogin | undefined>(() => {
@ -29,19 +29,19 @@ export const currentUser = computed<UserLogin | undefined>(() => {
return users.value[0] return users.value[0]
}) })
const publicInstance = ref<Instance | null>(null)
export const currentInstance = computed<null | Instance>(() => currentUser.value ? instances.value[currentUser.value.server] ?? null : publicInstance.value)
export const publicServer = ref(DEFAULT_SERVER)
export const currentServer = computed<string>(() => currentUser.value?.server || publicServer.value)
export const currentUserHandle = computed(() => currentUser.value?.account.id export const currentUserHandle = computed(() => currentUser.value?.account.id
? `${currentUser.value.account.acct}@${currentUser.value.server}` ? `${currentUser.value.account.acct}@${currentInstance.value?.uri || currentServer.value}`
: '[anonymous]', : '[anonymous]',
) )
export const publicServer = ref(DEFAULT_SERVER)
const publicInstance = ref<Instance | null>(null)
export const currentServer = computed<string>(() => currentUser.value?.server || publicServer.value)
export const useUsers = () => users export const useUsers = () => users
export const currentInstance = computed<null | Instance>(() => currentUserId.value ? servers.value[currentUserId.value] ?? null : publicInstance.value)
export const characterLimit = computed(() => currentInstance.value?.configuration.statuses.maxCharacters ?? DEFAULT_POST_CHARS_LIMIT) export const characterLimit = computed(() => currentInstance.value?.configuration.statuses.maxCharacters ?? DEFAULT_POST_CHARS_LIMIT)
export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: AccountCredentials }) { export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: AccountCredentials }) {
@ -62,7 +62,7 @@ export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: Ac
else { else {
try { try {
const [me, server, pushSubscription] = await Promise.all([ const [me, instance, pushSubscription] = await Promise.all([
masto.accounts.verifyCredentials(), masto.accounts.verifyCredentials(),
masto.instances.fetch(), masto.instances.fetch(),
// we get 404 response instead empty data // we get 404 response instead empty data
@ -72,10 +72,10 @@ export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: Ac
user.account = me user.account = me
user.pushSubscription = pushSubscription user.pushSubscription = pushSubscription
currentUserId.value = me.id currentUserId.value = me.id
servers.value[me.id] = server instances.value[server] = instance
if (!user.account.acct.includes('@')) if (!user.account.acct.includes('@'))
user.account.acct = `${user.account.acct}@${server.uri}` user.account.acct = `${user.account.acct}@${instance.uri}`
if (!users.value.some(u => u.server === user.server && u.token === user.token)) if (!users.value.some(u => u.server === user.server && u.token === user.token))
users.value.push(user as UserLogin) users.value.push(user as UserLogin)
@ -141,7 +141,8 @@ export async function signout() {
if (index !== -1) { if (index !== -1) {
// Clear stale data // Clear stale data
clearUserLocalStorage() clearUserLocalStorage()
delete servers.value[_currentUserId] if (!users.value.some((u, i) => u.server === currentUser.value!.server && i !== index))
delete instances.value[currentUser.value.server]
await removePushNotifications(currentUser.value) await removePushNotifications(currentUser.value)
@ -221,7 +222,7 @@ export function useUserLocalStorage<T extends object>(key: string, initial: () =
return computed(() => { return computed(() => {
const id = currentUser.value?.account.id const id = currentUser.value?.account.id
? `${currentUser.value.account.acct}@${currentUser.value.server}` ? `${currentUser.value.account.acct}@${currentInstance.value?.uri || currentServer.value}`
: '[anonymous]' : '[anonymous]'
all.value[id] = Object.assign(initial(), all.value[id] || {}) all.value[id] = Object.assign(initial(), all.value[id] || {})
return all.value[id] return all.value[id]
@ -237,7 +238,7 @@ export function clearUserLocalStorage(account?: Account) {
if (!account) if (!account)
return return
const id = `${account.acct}@${currentUser.value?.server}` const id = `${account.acct}@${currentInstance.value?.uri || currentServer.value}`
// @ts-expect-error bind value to the function // @ts-expect-error bind value to the function
;(useUserLocalStorage._ as Map<string, Ref<Record<string, any>>>).forEach((storage) => { ;(useUserLocalStorage._ as Map<string, Ref<Record<string, any>>>).forEach((storage) => {
if (storage.value[id]) if (storage.value[id])

View File

@ -12,8 +12,8 @@ export default defineNuxtPlugin(async (nuxtApp) => {
return initialised return initialised
if (key === 'loginTo') { if (key === 'loginTo') {
return (...args: any[]) => { return (...args: any[]): Promise<MastoClient> => {
apiPromise.value = loginTo(...args).then((r) => { return apiPromise.value = loginTo(...args).then((r) => {
api.value = r api.value = r
return masto return masto
}).catch(() => { }).catch(() => {
@ -23,20 +23,21 @@ export default defineNuxtPlugin(async (nuxtApp) => {
statusMessage: 'Could not log into account.', statusMessage: 'Could not log into account.',
}) })
}) })
return apiPromise
} }
} }
if (api.value && key in api.value) if (api.value && key in api.value)
return api.value[key as keyof MastoClient] return api.value[key as keyof MastoClient]
if (!api) { if (!api.value) {
return new Proxy({}, { return new Proxy({}, {
get(_, subkey) { get(_, subkey) {
return (...args: any[]) => apiPromise.value?.then((r: any) => r[key][subkey](...args)) return (...args: any[]) => apiPromise.value?.then((r: any) => r[key][subkey](...args))
}, },
}) })
} }
return undefined
}, },
}) })