Allow proxying of getSession
using OAuth session (#3820)
* Allow proxying of dpop bound requests by using service auth instead, for the `getSession` endpoint. * Show `getSession` data in example app * Add scope * strings * cleanup * tidy * tidy * Add transition:email scope to example app * strings * changeset * pr comments
This commit is contained in:
parent
36dbd41551
commit
8318c57187
5
.changeset/early-trains-share.md
Normal file
5
.changeset/early-trains-share.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@atproto/oauth-client-browser-example": patch
|
||||
---
|
||||
|
||||
Add `com.atproto.server.getSession` query.
|
5
.changeset/funny-moles-explain.md
Normal file
5
.changeset/funny-moles-explain.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@atproto/pds": patch
|
||||
---
|
||||
|
||||
Allow access to `com.atproto.server.getSession` when authenticated using oauth credentials. Email info (`email`, `emailConfirmed`) will only be exposed if the credentials were issued with the `transition:email` scope.
|
7
.changeset/shy-moose-fail.md
Normal file
7
.changeset/shy-moose-fail.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"@atproto/oauth-provider-ui": patch
|
||||
"@atproto/oauth-provider": patch
|
||||
"@atproto/pds": patch
|
||||
---
|
||||
|
||||
Add support for `transition:email` oauth scope
|
5
.changeset/silver-scissors-laugh.md
Normal file
5
.changeset/silver-scissors-laugh.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@atproto/oauth-client-browser-example": patch
|
||||
---
|
||||
|
||||
Allow configuration of loopback client id scope through query param
|
@ -45,7 +45,11 @@
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{ "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }
|
||||
{
|
||||
"argsIgnorePattern": "^_",
|
||||
"varsIgnorePattern": "^_",
|
||||
"ignoreRestSiblings": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
|
@ -26,7 +26,6 @@
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@atproto-labs/rollup-plugin-bundle-manifest": "workspace:*",
|
||||
"@atproto/api": "workspace:*",
|
||||
@ -35,17 +34,19 @@
|
||||
"@atproto/oauth-types": "workspace:*",
|
||||
"@atproto/xrpc": "workspace:*",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-html": "^1.0.4",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-swc": "^0.4.0",
|
||||
"@swc/helpers": "^0.5.15",
|
||||
"@tanstack/react-query": "^5.71.10",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"postcss": "^8.4.33",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-json-view": "^1.21.3",
|
||||
"rollup": "^4.13.0",
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"rollup-plugin-serve": "^1.1.1",
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { UseQueryResult, useQuery } from '@tanstack/react-query'
|
||||
import { JSX, useEffect } from 'react'
|
||||
import ReactJson from 'react-json-view'
|
||||
import { Agent } from '@atproto/api'
|
||||
import { OAuthSession } from '@atproto/oauth-client'
|
||||
import { useAuthContext } from './auth/auth-provider.tsx'
|
||||
@ -6,37 +8,7 @@ import { useAuthContext } from './auth/auth-provider.tsx'
|
||||
function App() {
|
||||
const { pdsAgent, signOut, refresh } = useAuthContext()
|
||||
|
||||
const hasTokenInfo = pdsAgent.sessionManager instanceof OAuthSession
|
||||
|
||||
const [tokeninfo, setTokeninfo] = useState<unknown>(undefined)
|
||||
const loadTokeninfo = useCallback(async () => {
|
||||
if (pdsAgent.sessionManager instanceof OAuthSession) {
|
||||
setTokeninfo(await pdsAgent.sessionManager.getTokenInfo())
|
||||
}
|
||||
}, [pdsAgent])
|
||||
|
||||
// A call that requires to be authenticated
|
||||
const [serviceAuth, setServiceAuth] = useState<unknown>(undefined)
|
||||
const loadServiceAuth = useCallback(async () => {
|
||||
const serviceAuth = await pdsAgent.com.atproto.server.getServiceAuth({
|
||||
aud: pdsAgent.assertDid,
|
||||
})
|
||||
console.log('serviceAuth', serviceAuth)
|
||||
setServiceAuth(serviceAuth.data)
|
||||
}, [pdsAgent])
|
||||
|
||||
// This call does not require authentication
|
||||
const [profile, setProfile] = useState<unknown>(undefined)
|
||||
const loadProfile = useCallback(async () => {
|
||||
const profile = await pdsAgent.com.atproto.repo.getRecord({
|
||||
repo: pdsAgent.assertDid,
|
||||
collection: 'app.bsky.actor.profile',
|
||||
rkey: 'self',
|
||||
})
|
||||
console.log(profile)
|
||||
setProfile(profile.data)
|
||||
}, [pdsAgent])
|
||||
|
||||
// Expose agent globally
|
||||
const global = window as { pdsAgent?: Agent }
|
||||
useEffect(() => {
|
||||
global.pdsAgent = pdsAgent
|
||||
@ -49,42 +21,144 @@ function App() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Logged in!</p>
|
||||
<p>
|
||||
Logged in!
|
||||
<div className="ml-2 inline-flex flex-wrap space-x-2">
|
||||
<Button onClick={refresh}>Refresh tokens</Button>
|
||||
<Button onClick={signOut}>Sign-out</Button>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
{hasTokenInfo && (
|
||||
<>
|
||||
<button onClick={loadTokeninfo}>Load token info</button>
|
||||
<code>
|
||||
<pre>
|
||||
{tokeninfo !== undefined
|
||||
? JSON.stringify(tokeninfo, undefined, 2)
|
||||
: null}
|
||||
</pre>
|
||||
</code>
|
||||
</>
|
||||
)}
|
||||
|
||||
<button onClick={loadProfile}>Load profile</button>
|
||||
<code>
|
||||
<pre>
|
||||
{profile !== undefined ? JSON.stringify(profile, undefined, 2) : null}
|
||||
</pre>
|
||||
</code>
|
||||
|
||||
<button onClick={loadServiceAuth}>Load service auth</button>
|
||||
<code>
|
||||
<pre>
|
||||
{serviceAuth !== undefined
|
||||
? JSON.stringify(serviceAuth, undefined, 2)
|
||||
: null}
|
||||
</pre>
|
||||
</code>
|
||||
|
||||
<button onClick={refresh}>Refresh tokens</button>
|
||||
<br />
|
||||
<button onClick={signOut}>Sign-out</button>
|
||||
{pdsAgent.sessionManager instanceof OAuthSession && <TokenInfo />}
|
||||
<SessionInfo />
|
||||
<ProfileInfo />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
|
||||
function TokenInfo() {
|
||||
const { pdsAgent } = useAuthContext()
|
||||
const { sessionManager } = pdsAgent
|
||||
|
||||
const oauthSession =
|
||||
sessionManager instanceof OAuthSession ? sessionManager : null
|
||||
|
||||
const result = useQuery({
|
||||
queryKey: ['tokeninfo', pdsAgent.assertDid],
|
||||
queryFn: async () => oauthSession?.getTokenInfo(),
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>
|
||||
Token info
|
||||
<Button
|
||||
className="ml-2"
|
||||
onClick={() => result.refetch({ throwOnError: false })}
|
||||
>
|
||||
refresh
|
||||
</Button>
|
||||
</h2>
|
||||
<QueryResult result={result} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ProfileInfo() {
|
||||
const { pdsAgent } = useAuthContext()
|
||||
|
||||
const result = useQuery({
|
||||
queryKey: ['profile', pdsAgent.assertDid],
|
||||
queryFn: async () => {
|
||||
const { data } = await pdsAgent.com.atproto.repo.getRecord({
|
||||
repo: pdsAgent.assertDid,
|
||||
collection: 'app.bsky.actor.profile',
|
||||
rkey: 'self',
|
||||
})
|
||||
return data
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>
|
||||
Profile
|
||||
<Button
|
||||
className="ml-2"
|
||||
onClick={() => result.refetch({ throwOnError: false })}
|
||||
>
|
||||
refresh
|
||||
</Button>
|
||||
</h2>
|
||||
<QueryResult result={result} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function SessionInfo() {
|
||||
const { pdsAgent } = useAuthContext()
|
||||
|
||||
const result = useQuery({
|
||||
queryKey: ['session', pdsAgent.assertDid],
|
||||
queryFn: async () => {
|
||||
const { data } = await pdsAgent.com.atproto.server.getSession()
|
||||
return data
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>
|
||||
getSession
|
||||
<Button
|
||||
className="ml-2"
|
||||
onClick={() => result.refetch({ throwOnError: false })}
|
||||
>
|
||||
refresh
|
||||
</Button>
|
||||
</h2>
|
||||
<QueryResult result={result} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function QueryResult({ result }: { result: UseQueryResult }) {
|
||||
return (
|
||||
<div>
|
||||
{result.data !== undefined ? (
|
||||
result.data === null ? (
|
||||
'null'
|
||||
) : (
|
||||
<ReactJson
|
||||
src={result.data}
|
||||
indentWidth={2}
|
||||
displayDataTypes={false}
|
||||
/>
|
||||
)
|
||||
) : result.isLoading ? (
|
||||
<p>Loading...</p>
|
||||
) : result.isError ? (
|
||||
<p>Error: {String(result.error)}</p>
|
||||
) : (
|
||||
<p>Error: no-data</p>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Button({
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: JSX.IntrinsicElements['button']) {
|
||||
return (
|
||||
<button
|
||||
{...props}
|
||||
className={`inline-block transform rounded bg-cyan-300 px-2 py-1 text-black shadow-lg transition duration-300 ease-in-out hover:scale-105 hover:bg-cyan-500 ${className || ''}`}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
@ -16,3 +16,9 @@ export const HANDLE_RESOLVER_URL: string =
|
||||
export const SIGN_UP_URL: string =
|
||||
searchParams.get('sign_up_url') ??
|
||||
(ENV === 'development' ? 'http://localhost:2583' : 'https://bsky.social')
|
||||
|
||||
export const OAUTH_SCOPE: string =
|
||||
searchParams.get('scope') ??
|
||||
(ENV === 'development'
|
||||
? 'atproto transition:generic transition:email transition:chat.bsky'
|
||||
: 'atproto transition:generic')
|
||||
|
@ -1,5 +1,6 @@
|
||||
import './index.css'
|
||||
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import App from './app.tsx'
|
||||
@ -7,33 +8,39 @@ import { AuthProvider } from './auth/auth-provider.tsx'
|
||||
import {
|
||||
ENV,
|
||||
HANDLE_RESOLVER_URL,
|
||||
OAUTH_SCOPE,
|
||||
PLC_DIRECTORY_URL,
|
||||
SIGN_UP_URL,
|
||||
} from './constants.ts'
|
||||
|
||||
const clientId = `http://localhost?${new URLSearchParams({
|
||||
scope: 'atproto transition:generic',
|
||||
scope: OAUTH_SCOPE,
|
||||
redirect_uri: Object.assign(new URL(window.location.origin), {
|
||||
hostname: '127.0.0.1',
|
||||
search: new URLSearchParams({
|
||||
env: ENV,
|
||||
handle_resolver: HANDLE_RESOLVER_URL,
|
||||
sign_up_url: SIGN_UP_URL,
|
||||
scope: OAUTH_SCOPE,
|
||||
...(PLC_DIRECTORY_URL && { plc_directory_url: PLC_DIRECTORY_URL }),
|
||||
}).toString(),
|
||||
}).href,
|
||||
})}`
|
||||
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<AuthProvider
|
||||
clientId={clientId}
|
||||
plcDirectoryUrl={PLC_DIRECTORY_URL}
|
||||
signUpUrl={SIGN_UP_URL}
|
||||
handleResolver={HANDLE_RESOLVER_URL}
|
||||
allowHttp={ENV === 'development' || ENV === 'test'}
|
||||
>
|
||||
<App />
|
||||
</AuthProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AuthProvider
|
||||
clientId={clientId}
|
||||
plcDirectoryUrl={PLC_DIRECTORY_URL}
|
||||
signUpUrl={SIGN_UP_URL}
|
||||
handleResolver={HANDLE_RESOLVER_URL}
|
||||
allowHttp={ENV === 'development' || ENV === 'test'}
|
||||
>
|
||||
<App />
|
||||
</AuthProvider>
|
||||
</QueryClientProvider>
|
||||
</StrictMode>,
|
||||
)
|
||||
|
@ -168,7 +168,8 @@
|
||||
createdAt: '2023-10-01T00:00:00.000Z',
|
||||
updatedAt: '2023-10-01T00:00:00.000Z',
|
||||
clientId: 'https://bsky.app/oauth-client.json',
|
||||
scope: 'atproto transition:generic transition:chat.bsky',
|
||||
scope:
|
||||
'atproto transition:generic transition:email transition:chat.bsky',
|
||||
},
|
||||
{
|
||||
tokenId: 'token3',
|
||||
|
@ -128,6 +128,7 @@
|
||||
scopeDetails: [
|
||||
{ scope: 'atproto' },
|
||||
{ scope: 'transition:generic' },
|
||||
{ scope: 'transition:email' },
|
||||
{ scope: 'transition:chat.bsky' },
|
||||
],
|
||||
}
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr "2FA Confirmation"
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr "A second authentication factor is required"
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr "Access your account data (except chat messages)"
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr "Access your chat messages"
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr "Please verify the domain name of the website before entering your passwo
|
||||
msgid "Privacy Policy"
|
||||
msgstr "Privacy Policy"
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr "Read your email address"
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr "Confirmation 2FA"
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr "Un second facteur d'authentification est requis"
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr "Accéder aux données de votre compte (sauf les messages de chat)"
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr "Accéder à vos messages de chat"
|
||||
|
||||
@ -60,7 +60,7 @@ msgstr "Authoriser l'accès"
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-picker.tsx:68
|
||||
msgid "Avatar"
|
||||
msgstr ""
|
||||
msgstr "Photo de profile"
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-picker.tsx:47
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:130
|
||||
@ -314,6 +314,10 @@ msgstr "Veuillez vérifier le nom de domaine du site web avant de saisir votre m
|
||||
msgid "Privacy Policy"
|
||||
msgstr "Politique de Confidentialité"
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr "Lire votre adresse email"
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -25,11 +25,11 @@ msgstr ""
|
||||
msgid "A second authentication factor is required"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
msgid "Access your account data (except chat messages)"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:150
|
||||
#: src/views/authorize/accept/accept-form.tsx:152
|
||||
msgid "Access your chat messages"
|
||||
msgstr ""
|
||||
|
||||
@ -314,6 +314,10 @@ msgstr ""
|
||||
msgid "Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/accept/accept-form.tsx:148
|
||||
msgid "Read your email address"
|
||||
msgstr ""
|
||||
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:205
|
||||
#: src/views/authorize/sign-in/sign-in-form.tsx:210
|
||||
msgid "Remember this account on this device"
|
||||
|
@ -144,6 +144,8 @@ function ScopeDescription({ scope }: ScopeDescriptionProps) {
|
||||
switch (scope) {
|
||||
case 'atproto':
|
||||
return <Trans>Uniquely identify you</Trans>
|
||||
case 'transition:email':
|
||||
return <Trans>Read your email address</Trans>
|
||||
case 'transition:generic':
|
||||
return <Trans>Access your account data (except chat messages)</Trans>
|
||||
case 'transition:chat.bsky':
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { ComAtprotoServerGetSession } from '@atproto/api'
|
||||
import { INVALID_HANDLE } from '@atproto/syntax'
|
||||
import { InvalidRequestError } from '@atproto/xrpc-server'
|
||||
import { formatAccountStatus } from '../../../../account-manager/account-manager'
|
||||
import { AuthScope } from '../../../../auth-verifier'
|
||||
import { AccessOutput, AuthScope, OAuthOutput } from '../../../../auth-verifier'
|
||||
import { AppContext } from '../../../../context'
|
||||
import { Server } from '../../../../lexicon'
|
||||
import { resultPassthru } from '../../../proxy'
|
||||
import { didDocForSession } from './util'
|
||||
|
||||
export default function (server: Server, ctx: AppContext) {
|
||||
@ -14,12 +14,25 @@ export default function (server: Server, ctx: AppContext) {
|
||||
}),
|
||||
handler: async ({ auth, req }) => {
|
||||
if (ctx.entrywayAgent) {
|
||||
return resultPassthru(
|
||||
await ctx.entrywayAgent.com.atproto.server.getSession(
|
||||
undefined,
|
||||
ctx.entrywayPassthruHeaders(req),
|
||||
),
|
||||
// Allow proxying of dpop bound requests by using service auth instead
|
||||
const headers =
|
||||
auth.credentials.type === 'oauth' // DPoP bound tokens cannot be proxied
|
||||
? await ctx.entrywayAuthHeaders(
|
||||
req,
|
||||
auth.credentials.did,
|
||||
'com.atproto.server.getSession',
|
||||
)
|
||||
: ctx.entrywayPassthruHeaders(req)
|
||||
|
||||
const res = await ctx.entrywayAgent.com.atproto.server.getSession(
|
||||
undefined,
|
||||
headers,
|
||||
)
|
||||
|
||||
return {
|
||||
encoding: 'application/json',
|
||||
body: output(auth, res.data),
|
||||
}
|
||||
}
|
||||
|
||||
const did = auth.credentials.did
|
||||
@ -37,7 +50,7 @@ export default function (server: Server, ctx: AppContext) {
|
||||
|
||||
return {
|
||||
encoding: 'application/json',
|
||||
body: {
|
||||
body: output(auth, {
|
||||
handle: user.handle ?? INVALID_HANDLE,
|
||||
did: user.did,
|
||||
email: user.email ?? undefined,
|
||||
@ -45,8 +58,30 @@ export default function (server: Server, ctx: AppContext) {
|
||||
emailConfirmed: !!user.emailConfirmedAt,
|
||||
active,
|
||||
status,
|
||||
},
|
||||
}),
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function output(
|
||||
{ credentials }: AccessOutput | OAuthOutput,
|
||||
data: ComAtprotoServerGetSession.OutputSchema,
|
||||
): ComAtprotoServerGetSession.OutputSchema {
|
||||
switch (credentials.type) {
|
||||
case 'access':
|
||||
return data
|
||||
|
||||
case 'oauth':
|
||||
if (!credentials.oauthScopes.has('transition:email')) {
|
||||
const { email, emailAuthFactor, emailConfirmed, ...rest } = data
|
||||
return rest
|
||||
}
|
||||
|
||||
return data
|
||||
|
||||
default:
|
||||
// @ts-expect-error
|
||||
throw new Error(`Unknown credentials type: ${credentials.type}`)
|
||||
}
|
||||
}
|
||||
|
@ -46,17 +46,17 @@ export enum RoleStatus {
|
||||
Missing,
|
||||
}
|
||||
|
||||
type NullOutput = {
|
||||
export type NullOutput = {
|
||||
credentials: null
|
||||
}
|
||||
|
||||
type AdminTokenOutput = {
|
||||
export type AdminTokenOutput = {
|
||||
credentials: {
|
||||
type: 'admin_token'
|
||||
}
|
||||
}
|
||||
|
||||
type ModServiceOutput = {
|
||||
export type ModServiceOutput = {
|
||||
credentials: {
|
||||
type: 'mod_service'
|
||||
aud: string
|
||||
@ -64,29 +64,35 @@ type ModServiceOutput = {
|
||||
}
|
||||
}
|
||||
|
||||
type AccessOutput = {
|
||||
export type AccessOutput = {
|
||||
credentials: {
|
||||
type: 'access'
|
||||
did: string
|
||||
scope: AuthScope
|
||||
audience: string | undefined
|
||||
isPrivileged: boolean
|
||||
}
|
||||
artifacts: string
|
||||
}
|
||||
|
||||
type RefreshOutput = {
|
||||
export type OAuthOutput = {
|
||||
credentials: {
|
||||
type: 'oauth'
|
||||
did: string
|
||||
scope: AuthScope
|
||||
isPrivileged: boolean
|
||||
oauthScopes: Set<string>
|
||||
}
|
||||
}
|
||||
|
||||
export type RefreshOutput = {
|
||||
credentials: {
|
||||
type: 'refresh'
|
||||
did: string
|
||||
scope: AuthScope
|
||||
audience: string | undefined
|
||||
tokenId: string
|
||||
}
|
||||
artifacts: string
|
||||
}
|
||||
|
||||
type UserServiceAuthOutput = {
|
||||
export type UserServiceAuthOutput = {
|
||||
credentials: {
|
||||
type: 'user_service_auth'
|
||||
aud: string
|
||||
@ -139,7 +145,7 @@ export class AuthVerifier {
|
||||
|
||||
accessStandard =
|
||||
(opts: Partial<AccessOpts> = {}) =>
|
||||
async (ctx: ReqCtx): Promise<AccessOutput> => {
|
||||
async (ctx: ReqCtx): Promise<AccessOutput | OAuthOutput> => {
|
||||
return this.validateAccessToken(
|
||||
ctx,
|
||||
[
|
||||
@ -154,7 +160,7 @@ export class AuthVerifier {
|
||||
|
||||
accessFull =
|
||||
(opts: Partial<AccessOpts> = {}) =>
|
||||
(ctx: ReqCtx): Promise<AccessOutput> => {
|
||||
(ctx: ReqCtx): Promise<AccessOutput | OAuthOutput> => {
|
||||
return this.validateAccessToken(
|
||||
ctx,
|
||||
[AuthScope.Access, ...(opts.additional ?? [])],
|
||||
@ -164,7 +170,7 @@ export class AuthVerifier {
|
||||
|
||||
accessPrivileged =
|
||||
(opts: Partial<AccessOpts> = {}) =>
|
||||
(ctx: ReqCtx): Promise<AccessOutput> => {
|
||||
(ctx: ReqCtx): Promise<AccessOutput | OAuthOutput> => {
|
||||
return this.validateAccessToken(ctx, [
|
||||
AuthScope.Access,
|
||||
AuthScope.AppPassPrivileged,
|
||||
@ -173,34 +179,30 @@ export class AuthVerifier {
|
||||
}
|
||||
|
||||
refresh = async (ctx: ReqCtx): Promise<RefreshOutput> => {
|
||||
const { did, scope, token, tokenId, audience } =
|
||||
await this.validateRefreshToken(ctx)
|
||||
const { did, scope, tokenId } = await this.validateRefreshToken(ctx)
|
||||
|
||||
return {
|
||||
credentials: {
|
||||
type: 'refresh',
|
||||
did,
|
||||
scope,
|
||||
audience,
|
||||
tokenId,
|
||||
},
|
||||
artifacts: token,
|
||||
}
|
||||
}
|
||||
|
||||
refreshExpired = async (ctx: ReqCtx): Promise<RefreshOutput> => {
|
||||
const { did, scope, token, tokenId, audience } =
|
||||
await this.validateRefreshToken(ctx, { clockTolerance: Infinity })
|
||||
const { did, scope, tokenId } = await this.validateRefreshToken(ctx, {
|
||||
clockTolerance: Infinity,
|
||||
})
|
||||
|
||||
return {
|
||||
credentials: {
|
||||
type: 'refresh',
|
||||
did,
|
||||
scope,
|
||||
audience,
|
||||
tokenId,
|
||||
},
|
||||
artifacts: token,
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,7 +215,7 @@ export class AuthVerifier {
|
||||
(opts: Partial<AccessOpts> = {}) =>
|
||||
async (
|
||||
ctx: ReqCtx,
|
||||
): Promise<AccessOutput | AdminTokenOutput | NullOutput> => {
|
||||
): Promise<AccessOutput | OAuthOutput | AdminTokenOutput | NullOutput> => {
|
||||
if (isAccessToken(ctx.req)) {
|
||||
return await this.accessStandard(opts)(ctx)
|
||||
} else if (isBasicToken(ctx.req)) {
|
||||
@ -258,7 +260,9 @@ export class AuthVerifier {
|
||||
|
||||
accessOrUserServiceAuth =
|
||||
(opts: Partial<AccessOpts> = {}) =>
|
||||
async (ctx: ReqCtx): Promise<UserServiceAuthOutput | AccessOutput> => {
|
||||
async (
|
||||
ctx: ReqCtx,
|
||||
): Promise<UserServiceAuthOutput | AccessOutput | OAuthOutput> => {
|
||||
const token = bearerTokenFromReq(ctx.req)
|
||||
if (token) {
|
||||
const payload = jose.decodeJwt(token)
|
||||
@ -411,10 +415,10 @@ export class AuthVerifier {
|
||||
checkTakedown = false,
|
||||
checkDeactivated = false,
|
||||
}: { checkTakedown?: boolean; checkDeactivated?: boolean } = {},
|
||||
): Promise<AccessOutput> {
|
||||
): Promise<AccessOutput | OAuthOutput> {
|
||||
this.setAuthHeaders(ctx)
|
||||
|
||||
let accessOutput: AccessOutput
|
||||
let accessOutput: AccessOutput | OAuthOutput
|
||||
|
||||
const [type] = parseAuthorizationHeader(ctx.req.headers.authorization)
|
||||
switch (type) {
|
||||
@ -467,7 +471,7 @@ export class AuthVerifier {
|
||||
protected async validateDpopAccessToken(
|
||||
ctx: ReqCtx,
|
||||
scopes: AuthScope[],
|
||||
): Promise<AccessOutput> {
|
||||
): Promise<OAuthOutput> {
|
||||
this.setAuthHeaders(ctx)
|
||||
|
||||
const { req } = ctx
|
||||
@ -498,16 +502,16 @@ export class AuthVerifier {
|
||||
throw new InvalidRequestError('Malformed token', 'InvalidToken')
|
||||
}
|
||||
|
||||
const tokenScopes = new Set(result.claims.scope?.split(' '))
|
||||
const oauthScopes = new Set(result.claims.scope?.split(' '))
|
||||
|
||||
if (!tokenScopes.has('transition:generic')) {
|
||||
if (!oauthScopes.has('transition:generic')) {
|
||||
throw new AuthRequiredError(
|
||||
'Missing required scope: transition:generic',
|
||||
'InvalidToken',
|
||||
)
|
||||
}
|
||||
|
||||
const scopeEquivalent: AuthScope = tokenScopes.has('transition:chat.bsky')
|
||||
const scopeEquivalent: AuthScope = oauthScopes.has('transition:chat.bsky')
|
||||
? AuthScope.AppPassPrivileged
|
||||
: AuthScope.AppPass
|
||||
|
||||
@ -530,13 +534,12 @@ export class AuthVerifier {
|
||||
|
||||
return {
|
||||
credentials: {
|
||||
type: 'access',
|
||||
type: 'oauth',
|
||||
did: result.claims.sub,
|
||||
scope: scopeEquivalent,
|
||||
audience: this.dids.pds,
|
||||
oauthScopes,
|
||||
isPrivileged: scopeEquivalent === AuthScope.AppPassPrivileged,
|
||||
},
|
||||
artifacts: result.token,
|
||||
}
|
||||
} catch (err) {
|
||||
// Make sure to include any WWW-Authenticate header in the response
|
||||
@ -558,24 +561,21 @@ export class AuthVerifier {
|
||||
ctx: ReqCtx,
|
||||
scopes: AuthScope[],
|
||||
): Promise<AccessOutput> {
|
||||
const { did, scope, token, audience } = await this.validateBearerToken(
|
||||
ctx,
|
||||
scopes,
|
||||
{ audience: this.dids.pds, typ: 'at+jwt' },
|
||||
)
|
||||
const isPrivileged = [
|
||||
AuthScope.Access,
|
||||
AuthScope.AppPassPrivileged,
|
||||
].includes(scope)
|
||||
const { did, scope } = await this.validateBearerToken(ctx, scopes, {
|
||||
audience: this.dids.pds,
|
||||
typ: 'at+jwt',
|
||||
})
|
||||
|
||||
const isPrivileged =
|
||||
scope === AuthScope.Access || scope === AuthScope.AppPassPrivileged
|
||||
|
||||
return {
|
||||
credentials: {
|
||||
type: 'access',
|
||||
did,
|
||||
scope,
|
||||
audience,
|
||||
isPrivileged,
|
||||
},
|
||||
artifacts: token,
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,7 +632,7 @@ export class AuthVerifier {
|
||||
}
|
||||
|
||||
isUserOrAdmin(
|
||||
auth: AccessOutput | AdminTokenOutput | NullOutput,
|
||||
auth: AccessOutput | OAuthOutput | AdminTokenOutput | NullOutput,
|
||||
did: string,
|
||||
): boolean {
|
||||
if (!auth.credentials) {
|
||||
|
@ -363,7 +363,11 @@ export class AppContext {
|
||||
safeFetch,
|
||||
metadata: {
|
||||
protected_resources: [new URL(cfg.oauth.issuer).origin],
|
||||
scopes_supported: ['transition:generic', 'transition:chat.bsky'],
|
||||
scopes_supported: [
|
||||
'transition:email',
|
||||
'transition:generic',
|
||||
'transition:chat.bsky',
|
||||
],
|
||||
},
|
||||
// If the PDS is both an authorization server & resource server (no
|
||||
// entryway), there is no need to use JWTs as access tokens. Instead,
|
||||
|
@ -503,6 +503,7 @@ export const PROTECTED_METHODS = new Set<string>([
|
||||
ids.ComAtprotoServerCreateAppPassword,
|
||||
ids.ComAtprotoServerDeactivateAccount,
|
||||
ids.ComAtprotoServerGetAccountInviteCodes,
|
||||
ids.ComAtprotoServerGetSession,
|
||||
ids.ComAtprotoServerListAppPasswords,
|
||||
ids.ComAtprotoServerRequestAccountDelete,
|
||||
ids.ComAtprotoServerRequestEmailConfirmation,
|
||||
|
174
pnpm-lock.yaml
generated
174
pnpm-lock.yaml
generated
@ -943,6 +943,9 @@ importers:
|
||||
'@swc/helpers':
|
||||
specifier: ^0.5.15
|
||||
version: 0.5.15
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.71.10
|
||||
version: 5.71.10(react@19.0.0)
|
||||
'@types/react':
|
||||
specifier: ^19.0.10
|
||||
version: 19.0.10
|
||||
@ -961,6 +964,9 @@ importers:
|
||||
react-dom:
|
||||
specifier: ^19.0.0
|
||||
version: 19.0.0(react@19.0.0)
|
||||
react-json-view:
|
||||
specifier: ^1.21.3
|
||||
version: 1.21.3(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0)
|
||||
rollup:
|
||||
specifier: ^4.13.0
|
||||
version: 4.34.9
|
||||
@ -9064,6 +9070,10 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/asap@2.0.6:
|
||||
resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
|
||||
dev: true
|
||||
|
||||
/asn1.js@5.4.1:
|
||||
resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
|
||||
dependencies:
|
||||
@ -9272,6 +9282,10 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/base16@1.0.0:
|
||||
resolution: {integrity: sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==}
|
||||
dev: true
|
||||
|
||||
/base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
|
||||
@ -9983,6 +9997,14 @@ packages:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
dev: true
|
||||
|
||||
/cross-fetch@3.2.0:
|
||||
resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==}
|
||||
dependencies:
|
||||
node-fetch: 2.7.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: true
|
||||
|
||||
/cross-spawn@5.1.0:
|
||||
resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
|
||||
dependencies:
|
||||
@ -11634,6 +11656,32 @@ packages:
|
||||
bser: 2.1.1
|
||||
dev: true
|
||||
|
||||
/fbemitter@3.0.0:
|
||||
resolution: {integrity: sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==}
|
||||
dependencies:
|
||||
fbjs: 3.0.5
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: true
|
||||
|
||||
/fbjs-css-vars@1.0.2:
|
||||
resolution: {integrity: sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==}
|
||||
dev: true
|
||||
|
||||
/fbjs@3.0.5:
|
||||
resolution: {integrity: sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==}
|
||||
dependencies:
|
||||
cross-fetch: 3.2.0
|
||||
fbjs-css-vars: 1.0.2
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
promise: 7.3.1
|
||||
setimmediate: 1.0.5
|
||||
ua-parser-js: 1.0.38
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: true
|
||||
|
||||
/fd-slicer@1.1.0:
|
||||
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
|
||||
dependencies:
|
||||
@ -11751,6 +11799,18 @@ packages:
|
||||
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
|
||||
dev: true
|
||||
|
||||
/flux@4.0.4(react@19.0.0):
|
||||
resolution: {integrity: sha512-NCj3XlayA2UsapRpM7va6wU1+9rE5FIL7qoMcmxWHRzbp0yujihMBm9BBHZ1MDIk5h5o2Bl6eGiCe8rYELAmYw==}
|
||||
peerDependencies:
|
||||
react: ^15.0.2 || ^16.0.0 || ^17.0.0
|
||||
dependencies:
|
||||
fbemitter: 3.0.0
|
||||
fbjs: 3.0.5
|
||||
react: 19.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: true
|
||||
|
||||
/follow-redirects@1.15.5:
|
||||
resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==}
|
||||
engines: {node: '>=4.0'}
|
||||
@ -13735,9 +13795,17 @@ packages:
|
||||
/lodash.camelcase@4.3.0:
|
||||
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
|
||||
|
||||
/lodash.curry@4.1.1:
|
||||
resolution: {integrity: sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==}
|
||||
dev: true
|
||||
|
||||
/lodash.defaults@4.2.0:
|
||||
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
||||
|
||||
/lodash.flow@3.5.0:
|
||||
resolution: {integrity: sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==}
|
||||
dev: true
|
||||
|
||||
/lodash.get@4.4.2:
|
||||
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
||||
deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
|
||||
@ -13816,6 +13884,13 @@ packages:
|
||||
resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==}
|
||||
dev: false
|
||||
|
||||
/loose-envify@1.4.0:
|
||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
dev: true
|
||||
|
||||
/lru-cache@10.2.0:
|
||||
resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==}
|
||||
engines: {node: 14 || >=16.14}
|
||||
@ -15523,6 +15598,12 @@ packages:
|
||||
engines: {node: '>=0.12'}
|
||||
dev: true
|
||||
|
||||
/promise@7.3.1:
|
||||
resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==}
|
||||
dependencies:
|
||||
asap: 2.0.6
|
||||
dev: true
|
||||
|
||||
/prompts@2.4.2:
|
||||
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
|
||||
engines: {node: '>= 6'}
|
||||
@ -15633,6 +15714,10 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/pure-color@1.3.0:
|
||||
resolution: {integrity: sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==}
|
||||
dev: true
|
||||
|
||||
/qs@6.11.0:
|
||||
resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
|
||||
engines: {node: '>=0.6'}
|
||||
@ -15684,6 +15769,15 @@ packages:
|
||||
minimist: 1.2.8
|
||||
strip-json-comments: 2.0.1
|
||||
|
||||
/react-base16-styling@0.6.0:
|
||||
resolution: {integrity: sha512-yvh/7CArceR/jNATXOKDlvTnPKPmGZz7zsenQ3jUwLzHkNUR0CvY3yGYJbWJ/nnxsL8Sgmt5cO3/SILVuPO6TQ==}
|
||||
dependencies:
|
||||
base16: 1.0.0
|
||||
lodash.curry: 4.1.1
|
||||
lodash.flow: 3.5.0
|
||||
pure-color: 1.3.0
|
||||
dev: true
|
||||
|
||||
/react-dom@19.0.0(react@19.0.0):
|
||||
resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
|
||||
peerDependencies:
|
||||
@ -15706,6 +15800,27 @@ packages:
|
||||
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
|
||||
dev: true
|
||||
|
||||
/react-json-view@1.21.3(@types/react@19.0.10)(react-dom@19.0.0)(react@19.0.0):
|
||||
resolution: {integrity: sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw==}
|
||||
peerDependencies:
|
||||
react: ^17.0.0 || ^16.3.0 || ^15.5.4
|
||||
react-dom: ^17.0.0 || ^16.3.0 || ^15.5.4
|
||||
dependencies:
|
||||
flux: 4.0.4(react@19.0.0)
|
||||
react: 19.0.0
|
||||
react-base16-styling: 0.6.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
react-lifecycles-compat: 3.0.4
|
||||
react-textarea-autosize: 8.5.9(@types/react@19.0.10)(react@19.0.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
- encoding
|
||||
dev: true
|
||||
|
||||
/react-lifecycles-compat@3.0.4:
|
||||
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
|
||||
dev: true
|
||||
|
||||
/react-remove-scroll-bar@2.3.8(@types/react@19.0.10)(react@19.0.0):
|
||||
resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
|
||||
engines: {node: '>=10'}
|
||||
@ -15757,6 +15872,20 @@ packages:
|
||||
tslib: 2.8.1
|
||||
dev: true
|
||||
|
||||
/react-textarea-autosize@8.5.9(@types/react@19.0.10)(react@19.0.0):
|
||||
resolution: {integrity: sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.22.10
|
||||
react: 19.0.0
|
||||
use-composed-ref: 1.4.0(@types/react@19.0.10)(react@19.0.0)
|
||||
use-latest: 1.3.0(@types/react@19.0.10)(react@19.0.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: true
|
||||
|
||||
/react@19.0.0:
|
||||
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -16269,6 +16398,10 @@ packages:
|
||||
has-property-descriptors: 1.0.2
|
||||
dev: true
|
||||
|
||||
/setimmediate@1.0.5:
|
||||
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||
dev: true
|
||||
|
||||
/setprototypeof@1.2.0:
|
||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||
|
||||
@ -17346,7 +17479,6 @@ packages:
|
||||
|
||||
/ua-parser-js@1.0.38:
|
||||
resolution: {integrity: sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==}
|
||||
dev: false
|
||||
|
||||
/ua-parser-js@2.0.3:
|
||||
resolution: {integrity: sha512-LZyXZdNttONW8LjzEH3Z8+6TE7RfrEiJqDKyh0R11p/kxvrV2o9DrT2FGZO+KVNs3k+drcIQ6C3En6wLnzJGpw==}
|
||||
@ -17506,6 +17638,46 @@ packages:
|
||||
tslib: 2.8.1
|
||||
dev: true
|
||||
|
||||
/use-composed-ref@1.4.0(@types/react@19.0.10)(react@19.0.0):
|
||||
resolution: {integrity: sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 19.0.10
|
||||
react: 19.0.0
|
||||
dev: true
|
||||
|
||||
/use-isomorphic-layout-effect@1.2.0(@types/react@19.0.10)(react@19.0.0):
|
||||
resolution: {integrity: sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 19.0.10
|
||||
react: 19.0.0
|
||||
dev: true
|
||||
|
||||
/use-latest@1.3.0(@types/react@19.0.10)(react@19.0.0):
|
||||
resolution: {integrity: sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 19.0.10
|
||||
react: 19.0.0
|
||||
use-isomorphic-layout-effect: 1.2.0(@types/react@19.0.10)(react@19.0.0)
|
||||
dev: true
|
||||
|
||||
/use-sidecar@1.1.3(@types/react@19.0.10)(react@19.0.0):
|
||||
resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
Loading…
x
Reference in New Issue
Block a user