[APP-1674] Add bday fallback for app passwords (#9513)
* Add bday fallback for app passwords
* Update birthdate copy, add isAppPassword handling on NoAccessScreen
* Update copy
* Update usage
* Bump API package
* HmmMMMmmm
Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
* s/a/your
Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
* Say hello
---------
Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
(cherry picked from commit b47f5f023e)
This commit is contained in:
+1
-1
@@ -72,7 +72,7 @@
|
|||||||
"icons:optimize": "svgo -f ./assets/icons"
|
"icons:optimize": "svgo -f ./assets/icons"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@atproto/api": "^0.18.4",
|
"@atproto/api": "^0.18.6",
|
||||||
"@bitdrift/react-native": "^0.6.8",
|
"@bitdrift/react-native": "^0.6.8",
|
||||||
"@braintree/sanitize-url": "^6.0.2",
|
"@braintree/sanitize-url": "^6.0.2",
|
||||||
"@bsky.app/alf": "^0.1.5",
|
"@bsky.app/alf": "^0.1.5",
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import {
|
|||||||
useCreateSupportLink,
|
useCreateSupportLink,
|
||||||
} from '#/lib/hooks/useCreateSupportLink'
|
} from '#/lib/hooks/useCreateSupportLink'
|
||||||
import {dateDiff, useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
import {dateDiff, useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
||||||
|
import {isAppPassword} from '#/lib/jwt'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {useIsBirthdateUpdateAllowed} from '#/state/birthdate'
|
import {useIsBirthdateUpdateAllowed} from '#/state/birthdate'
|
||||||
import {useSessionApi} from '#/state/session'
|
import {useSession, useSessionApi} from '#/state/session'
|
||||||
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||||
import {Admonition} from '#/components/Admonition'
|
import {Admonition} from '#/components/Admonition'
|
||||||
import {AgeAssuranceAppealDialog} from '#/components/ageAssurance/AgeAssuranceAppealDialog'
|
import {AgeAssuranceAppealDialog} from '#/components/ageAssurance/AgeAssuranceAppealDialog'
|
||||||
@@ -29,7 +30,7 @@ import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/ic
|
|||||||
import {createStaticClick, SimpleInlineLinkText} from '#/components/Link'
|
import {createStaticClick, SimpleInlineLinkText} from '#/components/Link'
|
||||||
import {Outlet as PortalOutlet} from '#/components/Portal'
|
import {Outlet as PortalOutlet} from '#/components/Portal'
|
||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {Text} from '#/components/Typography'
|
import {Span, Text} from '#/components/Typography'
|
||||||
import {BottomSheetOutlet} from '#/../modules/bottom-sheet'
|
import {BottomSheetOutlet} from '#/../modules/bottom-sheet'
|
||||||
import {useAgeAssurance} from '#/ageAssurance'
|
import {useAgeAssurance} from '#/ageAssurance'
|
||||||
import {useAgeAssuranceDataContext} from '#/ageAssurance/data'
|
import {useAgeAssuranceDataContext} from '#/ageAssurance/data'
|
||||||
@@ -54,6 +55,9 @@ export function NoAccessScreen() {
|
|||||||
const {logoutCurrentAccount} = useSessionApi()
|
const {logoutCurrentAccount} = useSessionApi()
|
||||||
const createSupportLink = useCreateSupportLink()
|
const createSupportLink = useCreateSupportLink()
|
||||||
|
|
||||||
|
const {currentAccount} = useSession()
|
||||||
|
const isUsingAppPassword = isAppPassword(currentAccount?.accessJwt || '')
|
||||||
|
|
||||||
const aa = useAgeAssurance()
|
const aa = useAgeAssurance()
|
||||||
const isBlocked = aa.state.status === aa.Status.Blocked
|
const isBlocked = aa.state.status === aa.Status.Blocked
|
||||||
const isAARegion = !!region
|
const isAARegion = !!region
|
||||||
@@ -139,6 +143,9 @@ export function NoAccessScreen() {
|
|||||||
{isAARegion ? (
|
{isAARegion ? (
|
||||||
<>
|
<>
|
||||||
<View style={[a.gap_lg]}>
|
<View style={[a.gap_lg]}>
|
||||||
|
<Text style={[textStyles]}>
|
||||||
|
<Trans>Hey there!</Trans>
|
||||||
|
</Text>
|
||||||
<Text style={[textStyles]}>
|
<Text style={[textStyles]}>
|
||||||
<Trans>
|
<Trans>
|
||||||
You are accessing Bluesky from a region that legally
|
You are accessing Bluesky from a region that legally
|
||||||
@@ -167,10 +174,20 @@ export function NoAccessScreen() {
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<View style={[a.gap_lg]}>
|
<View style={[a.gap_lg]}>
|
||||||
|
<Text style={[textStyles]}>
|
||||||
|
<Trans>Hi there!</Trans>
|
||||||
|
</Text>
|
||||||
<Text style={[textStyles]}>
|
<Text style={[textStyles]}>
|
||||||
<Trans>
|
<Trans>
|
||||||
It looks like you haven't added your birthdate. You must
|
In order to provide an age-appropriate experience, we need to
|
||||||
provide an accurate date of birth to use Bluesky.
|
know your birthdate. This is a one-time thing, and your data
|
||||||
|
will be kept private.
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
<Text style={[textStyles]}>
|
||||||
|
<Trans>
|
||||||
|
Set your birthdate below and we'll get you back to posting and
|
||||||
|
exploring in no time!
|
||||||
</Trans>
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
<Button
|
||||||
@@ -182,6 +199,17 @@ export function NoAccessScreen() {
|
|||||||
<Trans>Add your birthdate</Trans>
|
<Trans>Add your birthdate</Trans>
|
||||||
</ButtonText>
|
</ButtonText>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
{isUsingAppPassword && (
|
||||||
|
<Admonition type="info">
|
||||||
|
<Trans>
|
||||||
|
Hmm, it looks like you're logged in with an{' '}
|
||||||
|
<Span style={[a.italic]}>App Password</Span>. To set your
|
||||||
|
birthdate, you'll need to log in with your main account
|
||||||
|
password, or ask whomever controls this account to do so.
|
||||||
|
</Trans>
|
||||||
|
</Admonition>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ import {
|
|||||||
import {useAgent, useSession} from '#/state/session'
|
import {useAgent, useSession} from '#/state/session'
|
||||||
import * as debug from '#/ageAssurance/debug'
|
import * as debug from '#/ageAssurance/debug'
|
||||||
import {logger} from '#/ageAssurance/logger'
|
import {logger} from '#/ageAssurance/logger'
|
||||||
import {isLegacyBirthdateBug} from '#/ageAssurance/util'
|
import {
|
||||||
|
getBirthdateStringFromAge,
|
||||||
|
isLegacyBirthdateBug,
|
||||||
|
} from '#/ageAssurance/util'
|
||||||
import {IS_DEV} from '#/env'
|
import {IS_DEV} from '#/env'
|
||||||
import {device} from '#/storage'
|
import {device} from '#/storage'
|
||||||
|
|
||||||
@@ -324,6 +327,22 @@ export async function getOtherRequiredData({
|
|||||||
const data: OtherRequiredData = {
|
const data: OtherRequiredData = {
|
||||||
birthdate: prefs.birthDate ? prefs.birthDate.toISOString() : undefined,
|
birthdate: prefs.birthDate ? prefs.birthDate.toISOString() : undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we can't read a birthdate, it may be due to the user accessing the
|
||||||
|
* account via an app password. In that case, fall-back to declared age
|
||||||
|
* flags.
|
||||||
|
*/
|
||||||
|
if (!data.birthdate) {
|
||||||
|
if (prefs.declaredAge?.isOverAge18) {
|
||||||
|
data.birthdate = getBirthdateStringFromAge(18)
|
||||||
|
} else if (prefs.declaredAge?.isOverAge16) {
|
||||||
|
data.birthdate = getBirthdateStringFromAge(16)
|
||||||
|
} else if (prefs.declaredAge?.isOverAge13) {
|
||||||
|
data.birthdate = getBirthdateStringFromAge(13)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const did = getDidFromAgentSession(agent)
|
const did = getDidFromAgentSession(agent)
|
||||||
if (data && did && birthdateCache.has(did)) {
|
if (data && did && birthdateCache.has(did)) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -86,3 +86,12 @@ export function isUserUnderMinimumAge(birthDate: string) {
|
|||||||
export function isUserUnderAdultAge(birthDate: string) {
|
export function isUserUnderAdultAge(birthDate: string) {
|
||||||
return getAge(new Date(birthDate)) < 18
|
return getAge(new Date(birthDate)) < 18
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getBirthdateStringFromAge(age: number) {
|
||||||
|
const today = new Date()
|
||||||
|
return new Date(
|
||||||
|
today.getFullYear() - age,
|
||||||
|
today.getMonth(),
|
||||||
|
today.getDate() - 1, // set to day before to ensure age is reached
|
||||||
|
).toISOString()
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,3 +21,9 @@ export function isJwtExpired(token: string) {
|
|||||||
return true // invalid token or parse error
|
return true // invalid token or parse error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isAppPassword(token: string) {
|
||||||
|
const payload = jwtDecode(token)
|
||||||
|
// @ts-ignore
|
||||||
|
return payload.scope === 'com.atproto.appPass'
|
||||||
|
}
|
||||||
|
|||||||
@@ -96,6 +96,20 @@
|
|||||||
tlds "^1.234.0"
|
tlds "^1.234.0"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
|
"@atproto/api@^0.18.6":
|
||||||
|
version "0.18.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.18.6.tgz#04c26b97bda01cbe276dea523de6e4a184894c18"
|
||||||
|
integrity sha512-dkzy2OHSAGgzG9GExvOiwRY73EzVD2AiD3nksng+V6erG0kwLfbmVYjoP9mq9Y16BCXr/7q9lekfogthqU614Q==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/common-web" "^0.4.7"
|
||||||
|
"@atproto/lexicon" "^0.6.0"
|
||||||
|
"@atproto/syntax" "^0.4.2"
|
||||||
|
"@atproto/xrpc" "^0.7.7"
|
||||||
|
await-lock "^2.2.2"
|
||||||
|
multiformats "^9.9.0"
|
||||||
|
tlds "^1.234.0"
|
||||||
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@atproto/aws@^0.2.31":
|
"@atproto/aws@^0.2.31":
|
||||||
version "0.2.31"
|
version "0.2.31"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.31.tgz#e46d7db34ee57c4f9817269f1e73a7eddba2b9b8"
|
resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.31.tgz#e46d7db34ee57c4f9817269f1e73a7eddba2b9b8"
|
||||||
@@ -189,6 +203,15 @@
|
|||||||
"@atproto/lex-json" "0.0.2"
|
"@atproto/lex-json" "0.0.2"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
|
"@atproto/common-web@^0.4.7":
|
||||||
|
version "0.4.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.4.7.tgz#6318f1daef105139449ff088ded6bfc97f3b6d59"
|
||||||
|
integrity sha512-vjw2+81KPo2/SAbbARGn64Ln+6JTI0FTI4xk8if0ebBfDxFRmHb2oSN1y77hzNq/ybGHqA2mecfhS03pxC5+lg==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/lex-data" "0.0.3"
|
||||||
|
"@atproto/lex-json" "0.0.3"
|
||||||
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@atproto/common@0.1.0":
|
"@atproto/common@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/common/-/common-0.1.0.tgz#4216a8fef5b985ab62ac21252a0f8ca0f4a0f210"
|
resolved "https://registry.yarnpkg.com/@atproto/common/-/common-0.1.0.tgz#4216a8fef5b985ab62ac21252a0f8ca0f4a0f210"
|
||||||
@@ -337,6 +360,17 @@
|
|||||||
uint8arrays "3.0.0"
|
uint8arrays "3.0.0"
|
||||||
unicode-segmenter "^0.14.0"
|
unicode-segmenter "^0.14.0"
|
||||||
|
|
||||||
|
"@atproto/lex-data@0.0.3":
|
||||||
|
version "0.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/lex-data/-/lex-data-0.0.3.tgz#1ce1bd19e17af41b2991a2a02ad439a136dec4e9"
|
||||||
|
integrity sha512-ivo1IpY/EX+RIpxPgCf4cPhQo5bfu4nrpa1vJCt8hCm9SfoonJkDFGa0n4SMw4JnXZoUcGcrJ46L+D8bH6GI2g==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/syntax" "0.4.2"
|
||||||
|
multiformats "^9.9.0"
|
||||||
|
tslib "^2.8.1"
|
||||||
|
uint8arrays "3.0.0"
|
||||||
|
unicode-segmenter "^0.14.0"
|
||||||
|
|
||||||
"@atproto/lex-document@0.0.4":
|
"@atproto/lex-document@0.0.4":
|
||||||
version "0.0.4"
|
version "0.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/lex-document/-/lex-document-0.0.4.tgz#2ada83e30bcef84cc0ff010c5dd8eb2514160731"
|
resolved "https://registry.yarnpkg.com/@atproto/lex-document/-/lex-document-0.0.4.tgz#2ada83e30bcef84cc0ff010c5dd8eb2514160731"
|
||||||
@@ -354,6 +388,14 @@
|
|||||||
"@atproto/lex-data" "0.0.2"
|
"@atproto/lex-data" "0.0.2"
|
||||||
tslib "^2.8.1"
|
tslib "^2.8.1"
|
||||||
|
|
||||||
|
"@atproto/lex-json@0.0.3":
|
||||||
|
version "0.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/lex-json/-/lex-json-0.0.3.tgz#c74aa0ede948b79ccc7fc8d9d1a3501a81c1cd8d"
|
||||||
|
integrity sha512-ZVcY7XlRfdPYvQQ2WroKUepee0+NCovrSXgXURM3Xv+n5jflJCoczguROeRr8sN0xvT0ZbzMrDNHCUYKNnxcjw==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/lex-data" "0.0.3"
|
||||||
|
tslib "^2.8.1"
|
||||||
|
|
||||||
"@atproto/lex-resolver@0.0.4":
|
"@atproto/lex-resolver@0.0.4":
|
||||||
version "0.0.4"
|
version "0.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/lex-resolver/-/lex-resolver-0.0.4.tgz#769b10e95860a055bce6d7dbf876f2d7612b1c7a"
|
resolved "https://registry.yarnpkg.com/@atproto/lex-resolver/-/lex-resolver-0.0.4.tgz#769b10e95860a055bce6d7dbf876f2d7612b1c7a"
|
||||||
@@ -389,6 +431,17 @@
|
|||||||
multiformats "^9.9.0"
|
multiformats "^9.9.0"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
|
"@atproto/lexicon@^0.6.0":
|
||||||
|
version "0.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.6.0.tgz#444e340ba651f34725787d11916436f507770f09"
|
||||||
|
integrity sha512-5veb8aD+J5M0qszLJ+73KSFsFrJBgAY/nM1TSAJvGY7fNc9ZAT+PSUlmIyrdye9YznAZ07yktalls/TwNV7cHQ==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/common-web" "^0.4.7"
|
||||||
|
"@atproto/syntax" "^0.4.2"
|
||||||
|
iso-datestring-validator "^2.2.2"
|
||||||
|
multiformats "^9.9.0"
|
||||||
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@atproto/oauth-provider-api@0.3.4":
|
"@atproto/oauth-provider-api@0.3.4":
|
||||||
version "0.3.4"
|
version "0.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-api/-/oauth-provider-api-0.3.4.tgz#bce9b1a5a6bd759b0de8f6b80c4aced9b64f0c79"
|
resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-api/-/oauth-provider-api-0.3.4.tgz#bce9b1a5a6bd759b0de8f6b80c4aced9b64f0c79"
|
||||||
@@ -621,6 +674,14 @@
|
|||||||
"@atproto/lexicon" "^0.5.2"
|
"@atproto/lexicon" "^0.5.2"
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
|
|
||||||
|
"@atproto/xrpc@^0.7.7":
|
||||||
|
version "0.7.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.7.7.tgz#c0e3106c854cb9bc7d3129de2f31b8256eb0ed11"
|
||||||
|
integrity sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==
|
||||||
|
dependencies:
|
||||||
|
"@atproto/lexicon" "^0.6.0"
|
||||||
|
zod "^3.23.8"
|
||||||
|
|
||||||
"@aws-crypto/crc32@5.2.0":
|
"@aws-crypto/crc32@5.2.0":
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-5.2.0.tgz#cfcc22570949c98c6689cfcbd2d693d36cdae2e1"
|
resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-5.2.0.tgz#cfcc22570949c98c6689cfcbd2d693d36cdae2e1"
|
||||||
|
|||||||
Reference in New Issue
Block a user