Url Auth: Support apps (#6896)
This commit is contained in:
parent
d5ec8153db
commit
fa6224abb7
@ -34,6 +34,8 @@ You are an expert in TypeScript, JavaScript, HTML, SCSS and Teact with deep expe
|
||||
- Functions should start with a verb (e.g. `openModal`, `closeDialog`, `handleClick`).
|
||||
- Prefer checking required parameter before calling a function, avoid making it optional and checking at the beginning of the function.
|
||||
- Only leave comments for complex logic.
|
||||
- Avoid using default values for props that can be intentionally undefined/false.
|
||||
- No unnecessary `as` casts. Prefer `satisfies` where possible.
|
||||
- Do not use `null`. There's linter rule to enforce it.
|
||||
- **IMPORTANT: Avoid conditional spread operators** - TypeScript doesn't check if spread fields match the target type.
|
||||
```typescript
|
||||
@ -180,7 +182,7 @@ addActionHandler('loadUser', async (global, actions, { userId }) => {
|
||||
### 3. Hooks
|
||||
* **useLastCallback** is your go-to for callbacks, since it won't trigger re-renders and always uses the latest scope.
|
||||
* Only use **useCallback** when you really need to memoize a render function.
|
||||
* Prefer **useFlag()** over `useState<boolean>()` for simple boolean toggles.
|
||||
* Prefer **useFlag()** over `useState<boolean>()` for simple boolean toggles. `useState` is preferred when component just calls `setState(someVariable)`.
|
||||
* Check the `hooks/` folders for additional utilities.
|
||||
* Avoid adding new `useEffect` where possible.
|
||||
|
||||
|
||||
@ -168,7 +168,7 @@ export function buildApiUrlAuthResult(result: GramJs.TypeUrlAuthResult): ApiUrlA
|
||||
if (result instanceof GramJs.UrlAuthResultRequest) {
|
||||
const {
|
||||
bot, domain, requestWriteAccess, requestPhoneNumber, browser, platform, ip, region, matchCodes,
|
||||
matchCodesFirst, userIdHint,
|
||||
matchCodesFirst, userIdHint, isApp, verifiedAppName,
|
||||
} = result;
|
||||
const user = buildApiUser(bot);
|
||||
if (!user) return undefined;
|
||||
@ -178,6 +178,7 @@ export function buildApiUrlAuthResult(result: GramJs.TypeUrlAuthResult): ApiUrlA
|
||||
return {
|
||||
type: 'request',
|
||||
domain,
|
||||
isApp,
|
||||
shouldRequestWriteAccess: requestWriteAccess,
|
||||
bot: user,
|
||||
shouldRequestPhoneNumber: requestPhoneNumber,
|
||||
@ -188,6 +189,7 @@ export function buildApiUrlAuthResult(result: GramJs.TypeUrlAuthResult): ApiUrlA
|
||||
matchCodes,
|
||||
matchCodesFirst,
|
||||
userIdHint: userIdHint?.toString(),
|
||||
verifiedAppName,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -389,6 +389,7 @@ export type ApiUrlAuthResultRequest = {
|
||||
type: 'request';
|
||||
bot: ApiUser;
|
||||
domain: string;
|
||||
isApp?: boolean;
|
||||
shouldRequestWriteAccess?: boolean;
|
||||
shouldRequestPhoneNumber?: boolean;
|
||||
browser?: string;
|
||||
@ -398,6 +399,7 @@ export type ApiUrlAuthResultRequest = {
|
||||
matchCodes?: string[];
|
||||
matchCodesFirst?: boolean;
|
||||
userIdHint?: string;
|
||||
verifiedAppName?: string;
|
||||
};
|
||||
|
||||
type ApiUrlAuthResultAccepted = {
|
||||
|
||||
@ -613,6 +613,7 @@
|
||||
"OpenUrlText" = "Do you want to open **{url}**?";
|
||||
"OpenUrlConfirm" = "Open";
|
||||
"BotAuthTitle" = "Log in to {url}";
|
||||
"BotAuthAppSubtitle" = "This app will receive your **name**, **username** and **profile photo**.";
|
||||
"BotAuthSiteSubtitle" = "This site will receive your **name**, **username** and **profile photo**.";
|
||||
"BotAuthAllowMessages" = "Allow Messages";
|
||||
"BotAuthAllowMessagesInfo" = "This will allow **{bot}** to message you.";
|
||||
@ -2007,6 +2008,7 @@
|
||||
"ActionBotAllowedFromDomain" = "You allowed this bot to message you when you logged in on {domain}.";
|
||||
"ActionBotAllowedFromApp" = "You allowed this bot to message you when you opened {app}.";
|
||||
"ActionBotAppPlaceholder" = "App";
|
||||
"BotAuthUnverifiedApp" = "Unverified App";
|
||||
"ActionGiftTextUnknown" = "You've received a gift";
|
||||
"ActionGiftTextUnknownYou" = "You sent a gift";
|
||||
"ActionGiftTextCost" = "{from} sent you a gift for {cost}";
|
||||
|
||||
@ -163,13 +163,19 @@ const UrlAuthModal = ({
|
||||
|| renderingRequest.browser || renderingRequest.ip || renderingRequest.region,
|
||||
);
|
||||
const requestDomain = renderingRequest.domain;
|
||||
const requestDisplayName = renderingRequest.isApp
|
||||
? renderingRequest.verifiedAppName || lang('BotAuthUnverifiedApp')
|
||||
: requestDomain;
|
||||
const titleTarget = renderingRequest.isApp
|
||||
? requestDisplayName
|
||||
: <SafeLink url={requestDomain} text={requestDomain} />;
|
||||
const formattedPhoneNumber = currentUser?.phoneNumber ? `+${formatPhoneNumber(currentUser.phoneNumber)}` : undefined;
|
||||
const titleText = lang('BotAuthTitle', {
|
||||
url: <SafeLink url={requestDomain} text={requestDomain} />,
|
||||
url: titleTarget,
|
||||
}, {
|
||||
withNodes: true,
|
||||
});
|
||||
const descriptionText = lang('BotAuthSiteSubtitle', undefined, {
|
||||
const descriptionText = lang(renderingRequest.isApp ? 'BotAuthAppSubtitle' : 'BotAuthSiteSubtitle', undefined, {
|
||||
withNodes: true,
|
||||
withMarkdown: true,
|
||||
});
|
||||
@ -179,7 +185,7 @@ const UrlAuthModal = ({
|
||||
<>
|
||||
<p>
|
||||
{lang('BotAuthPhoneNumberText', {
|
||||
domain: requestDomain,
|
||||
domain: requestDisplayName,
|
||||
phone: formattedPhoneNumber || lang('Phone'),
|
||||
}, {
|
||||
withNodes: true,
|
||||
@ -308,7 +314,7 @@ const UrlAuthModal = ({
|
||||
</div>
|
||||
<div className={styles.footnote}>
|
||||
{lang('BotAuthTitle', {
|
||||
url: <SafeLink url={requestDomain} text={requestDomain} />,
|
||||
url: titleTarget,
|
||||
}, {
|
||||
withNodes: true,
|
||||
})}
|
||||
|
||||
@ -18,7 +18,7 @@ import { copyTextToClipboard } from '../../../util/clipboard';
|
||||
import { getUsernameFromDeepLink } from '../../../util/deepLinkParser';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { pick } from '../../../util/iteratees.ts';
|
||||
import { getTranslationFn } from '../../../util/localization';
|
||||
import { type AdvancedLangFnParameters, getTranslationFn } from '../../../util/localization';
|
||||
import { formatStarsAsText } from '../../../util/localization/format';
|
||||
import { oldTranslate } from '../../../util/oldLangProvider';
|
||||
import requestActionTimeout from '../../../util/requestActionTimeout';
|
||||
@ -1298,41 +1298,28 @@ function handleUrlAuthResult<T extends GlobalState>(
|
||||
}
|
||||
|
||||
if (result.type === 'accepted' && !result.url) {
|
||||
if (!wasPhoneShared && tabState.urlAuth?.request?.shouldRequestPhoneNumber) {
|
||||
actions.showNotification({
|
||||
message: {
|
||||
key: 'BotAuthSuccessTextNoPhone',
|
||||
variables: {
|
||||
url: tabState.urlAuth.request?.domain || result.url,
|
||||
},
|
||||
options: {
|
||||
withMarkdown: true,
|
||||
withNodes: true,
|
||||
},
|
||||
},
|
||||
title: {
|
||||
key: 'BotAuthSuccessTitle',
|
||||
},
|
||||
tabId,
|
||||
});
|
||||
} else {
|
||||
actions.showNotification({
|
||||
message: {
|
||||
key: 'BotAuthSuccessText',
|
||||
variables: {
|
||||
url: tabState.urlAuth?.request?.domain || result.url,
|
||||
},
|
||||
options: {
|
||||
withMarkdown: true,
|
||||
withNodes: true,
|
||||
},
|
||||
},
|
||||
title: {
|
||||
key: 'BotAuthSuccessTitle',
|
||||
},
|
||||
tabId,
|
||||
});
|
||||
}
|
||||
const request = tabState.urlAuth?.request;
|
||||
const requestDisplayName = request?.isApp
|
||||
? (request.verifiedAppName || getTranslationFn()('BotAuthUnverifiedApp'))
|
||||
: (request?.domain || url);
|
||||
const successMessage: AdvancedLangFnParameters = {
|
||||
key: !wasPhoneShared && request?.shouldRequestPhoneNumber ? 'BotAuthSuccessTextNoPhone' : 'BotAuthSuccessText',
|
||||
variables: {
|
||||
url: requestDisplayName,
|
||||
},
|
||||
options: {
|
||||
withMarkdown: true,
|
||||
withNodes: true,
|
||||
},
|
||||
};
|
||||
|
||||
actions.showNotification({
|
||||
message: successMessage,
|
||||
title: {
|
||||
key: 'BotAuthSuccessTitle',
|
||||
},
|
||||
tabId,
|
||||
});
|
||||
actions.closeUrlAuthModal({ tabId });
|
||||
return;
|
||||
}
|
||||
|
||||
2
src/types/language.d.ts
vendored
2
src/types/language.d.ts
vendored
@ -549,6 +549,7 @@ export interface LangPair {
|
||||
'AboutPremiumDescription2': undefined;
|
||||
'OpenUrlTitle': undefined;
|
||||
'OpenUrlConfirm': undefined;
|
||||
'BotAuthAppSubtitle': undefined;
|
||||
'BotAuthSiteSubtitle': undefined;
|
||||
'BotAuthAllowMessages': undefined;
|
||||
'BotAuthInfo': undefined;
|
||||
@ -1589,6 +1590,7 @@ export interface LangPair {
|
||||
'NoForwardsRequestSaving': undefined;
|
||||
'NoForwardsRequestCopying': undefined;
|
||||
'ActionBotAppPlaceholder': undefined;
|
||||
'BotAuthUnverifiedApp': undefined;
|
||||
'ActionGiftTextUnknown': undefined;
|
||||
'ActionGiftTextUnknownYou': undefined;
|
||||
'ActionGiftUniqueSent': undefined;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user