Mini App: Fix geolocation check (#6898)
This commit is contained in:
parent
fa6224abb7
commit
e30555d3b3
@ -36,7 +36,7 @@ const LocationAccessModal: FC<OwnProps & StateProps> = ({
|
|||||||
currentUser,
|
currentUser,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
closeLocationAccessModal, toggleUserLocationPermission, sendWebAppEvent,
|
closeLocationAccessModal, toggleUserLocationPermission, sendWebAppEvent, showNotification,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
const isOpen = Boolean(modal);
|
const isOpen = Boolean(modal);
|
||||||
@ -47,28 +47,48 @@ const LocationAccessModal: FC<OwnProps & StateProps> = ({
|
|||||||
const containerRef = useRef<HTMLDivElement>();
|
const containerRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
const confirmHandler = useLastCallback(async () => {
|
const confirmHandler = useLastCallback(async () => {
|
||||||
const geolocationData = await getGeolocationStatus();
|
|
||||||
const { geolocation } = geolocationData;
|
|
||||||
if (!modal?.bot?.id) return;
|
if (!modal?.bot?.id) return;
|
||||||
|
|
||||||
|
const geolocationData = await getGeolocationStatus();
|
||||||
|
const { accessRequested, accessGranted, geolocation } = geolocationData;
|
||||||
|
const isAccessGranted = accessRequested && accessGranted && Boolean(geolocation);
|
||||||
closeLocationAccessModal();
|
closeLocationAccessModal();
|
||||||
if (modal?.webAppKey) {
|
if (modal?.webAppKey) {
|
||||||
toggleUserLocationPermission({
|
toggleUserLocationPermission({
|
||||||
botId: modal.bot.id,
|
botId: modal.bot.id,
|
||||||
isAccessGranted: true,
|
isAccessGranted,
|
||||||
});
|
});
|
||||||
|
if (!isAccessGranted || !geolocation) {
|
||||||
|
sendWebAppEvent({
|
||||||
|
webAppKey: modal.webAppKey,
|
||||||
|
event: {
|
||||||
|
eventType: 'location_requested',
|
||||||
|
eventData: {
|
||||||
|
available: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
showNotification({ message: oldLang('PermissionNoLocationPosition') });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sendWebAppEvent({
|
sendWebAppEvent({
|
||||||
webAppKey: modal.webAppKey,
|
webAppKey: modal.webAppKey,
|
||||||
event: {
|
event: {
|
||||||
eventType: 'location_requested',
|
eventType: 'location_requested',
|
||||||
eventData: {
|
eventData: {
|
||||||
available: true,
|
available: true,
|
||||||
latitude: geolocation?.latitude,
|
latitude: geolocation.latitude,
|
||||||
longitude: geolocation?.longitude,
|
longitude: geolocation.longitude,
|
||||||
altitude: geolocation?.altitude,
|
altitude: geolocation.altitude,
|
||||||
course: geolocation?.heading,
|
course: geolocation.heading,
|
||||||
speed: geolocation?.speed,
|
speed: geolocation.speed,
|
||||||
horizontal_accuracy: geolocation?.accuracy,
|
horizontal_accuracy: geolocation.accuracy,
|
||||||
vertical_accuracy: geolocation?.accuracy,
|
vertical_accuracy: geolocation.altitudeAccuracy,
|
||||||
|
// eslint-disable-next-line no-null/no-null
|
||||||
|
course_accuracy: null,
|
||||||
|
// eslint-disable-next-line no-null/no-null
|
||||||
|
speed_accuracy: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -321,6 +321,35 @@ const WebAppModalTabContent: FC<OwnProps & StateProps> = ({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const sendLocationUnavailable = useLastCallback(() => {
|
||||||
|
sendEvent({
|
||||||
|
eventType: 'location_requested',
|
||||||
|
eventData: {
|
||||||
|
available: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const sendLocation = useLastCallback((geolocation: GeolocationCoordinates) => {
|
||||||
|
sendEvent({
|
||||||
|
eventType: 'location_requested',
|
||||||
|
eventData: {
|
||||||
|
available: true,
|
||||||
|
latitude: geolocation.latitude,
|
||||||
|
longitude: geolocation.longitude,
|
||||||
|
altitude: geolocation.altitude,
|
||||||
|
course: geolocation.heading,
|
||||||
|
speed: geolocation.speed,
|
||||||
|
horizontal_accuracy: geolocation.accuracy,
|
||||||
|
vertical_accuracy: geolocation.altitudeAccuracy,
|
||||||
|
// eslint-disable-next-line no-null/no-null
|
||||||
|
course_accuracy: null,
|
||||||
|
// eslint-disable-next-line no-null/no-null
|
||||||
|
speed_accuracy: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const handleAppPopupModalClose = useLastCallback(() => {
|
const handleAppPopupModalClose = useLastCallback(() => {
|
||||||
handleAppPopupClose();
|
handleAppPopupClose();
|
||||||
});
|
});
|
||||||
@ -773,10 +802,20 @@ const WebAppModalTabContent: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
if (eventType === 'web_app_check_location') {
|
if (eventType === 'web_app_check_location') {
|
||||||
const handleGeolocationCheck = () => {
|
const handleGeolocationCheck = () => {
|
||||||
|
if (!isAvailable) {
|
||||||
|
sendEvent({
|
||||||
|
eventType: 'location_checked',
|
||||||
|
eventData: {
|
||||||
|
available: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sendEvent({
|
sendEvent({
|
||||||
eventType: 'location_checked',
|
eventType: 'location_checked',
|
||||||
eventData: {
|
eventData: {
|
||||||
available: isAvailable,
|
available: true,
|
||||||
access_requested: isAccessRequested,
|
access_requested: isAccessRequested,
|
||||||
access_granted: isAccessGranted,
|
access_granted: isAccessGranted,
|
||||||
},
|
},
|
||||||
@ -788,43 +827,38 @@ const WebAppModalTabContent: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
if (eventType === 'web_app_request_location') {
|
if (eventType === 'web_app_request_location') {
|
||||||
const handleRequestLocation = async () => {
|
const handleRequestLocation = async () => {
|
||||||
const geolocationData = await getGeolocationStatus();
|
if (!isAvailable) {
|
||||||
const { accessRequested, accessGranted, geolocation } = geolocationData;
|
sendLocationUnavailable();
|
||||||
|
|
||||||
if (!accessGranted || !accessRequested) {
|
|
||||||
sendEvent({
|
|
||||||
eventType: 'location_requested',
|
|
||||||
eventData: {
|
|
||||||
available: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
showNotification({ message: oldLang('PermissionNoLocationPosition') });
|
showNotification({ message: oldLang('PermissionNoLocationPosition') });
|
||||||
handleAppPopupClose(undefined);
|
handleAppPopupClose(undefined);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAvailable) {
|
if (!isAccessRequested) {
|
||||||
if (isAccessRequested) {
|
if (bot && webAppKey) {
|
||||||
sendEvent({
|
|
||||||
eventType: 'location_requested',
|
|
||||||
eventData: {
|
|
||||||
available: Boolean(botAppPermissions?.geolocation),
|
|
||||||
latitude: geolocation?.latitude,
|
|
||||||
longitude: geolocation?.longitude,
|
|
||||||
altitude: geolocation?.altitude,
|
|
||||||
course: geolocation?.heading,
|
|
||||||
speed: geolocation?.speed,
|
|
||||||
horizontal_accuracy: geolocation?.accuracy,
|
|
||||||
vertical_accuracy: geolocation?.altitudeAccuracy,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
openLocationAccessModal({ bot, webAppKey });
|
openLocationAccessModal({ bot, webAppKey });
|
||||||
|
} else {
|
||||||
|
sendLocationUnavailable();
|
||||||
}
|
}
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isAccessGranted) {
|
||||||
|
sendLocationUnavailable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const geolocationData = await getGeolocationStatus();
|
||||||
|
const { accessRequested, accessGranted, geolocation } = geolocationData;
|
||||||
|
|
||||||
|
if (!accessGranted || !accessRequested || !geolocation) {
|
||||||
|
sendLocationUnavailable();
|
||||||
showNotification({ message: oldLang('PermissionNoLocationPosition') });
|
showNotification({ message: oldLang('PermissionNoLocationPosition') });
|
||||||
handleAppPopupClose(undefined);
|
handleAppPopupClose(undefined);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendLocation(geolocation);
|
||||||
};
|
};
|
||||||
|
|
||||||
handleRequestLocation();
|
handleRequestLocation();
|
||||||
|
|||||||
@ -61,7 +61,7 @@ export const MEDIA_PROGRESSIVE_CACHE_DISABLED = false;
|
|||||||
export const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive';
|
export const MEDIA_PROGRESSIVE_CACHE_NAME = 'tt-media-progressive';
|
||||||
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
|
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
|
||||||
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
|
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
|
||||||
export const LANG_CACHE_NAME = 'tt-lang-packs-v51';
|
export const LANG_CACHE_NAME = 'tt-lang-packs-v52';
|
||||||
export const ASSET_CACHE_NAME = 'tt-assets';
|
export const ASSET_CACHE_NAME = 'tt-assets';
|
||||||
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
||||||
export const DATA_BROADCAST_CHANNEL_PREFIX = 'tt-global';
|
export const DATA_BROADCAST_CHANNEL_PREFIX = 'tt-global';
|
||||||
|
|||||||
@ -55,6 +55,31 @@ import {
|
|||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
|
|
||||||
const LOCAL_BOOST_COOLDOWN = 86400; // 24 hours
|
const LOCAL_BOOST_COOLDOWN = 86400; // 24 hours
|
||||||
|
const SMART_GLOCAL_DOMAIN = 'smart-glocal.com';
|
||||||
|
const SMART_GLOCAL_TOKENIZE_PATH = '/cds/v1/tokenize/card';
|
||||||
|
|
||||||
|
function isValidSmartGlocalTokenizeUrl(tokenizeUrl: string) {
|
||||||
|
if (tokenizeUrl !== tokenizeUrl.trim()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsedUrl: URL;
|
||||||
|
try {
|
||||||
|
parsedUrl = new URL(tokenizeUrl);
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { protocol, hostname, pathname, port, username, password } = parsedUrl;
|
||||||
|
const isSmartGlocalHost = hostname === SMART_GLOCAL_DOMAIN || hostname.endsWith(`.${SMART_GLOCAL_DOMAIN}`);
|
||||||
|
|
||||||
|
return protocol === 'https:'
|
||||||
|
&& isSmartGlocalHost
|
||||||
|
&& pathname === SMART_GLOCAL_TOKENIZE_PATH
|
||||||
|
&& !port
|
||||||
|
&& !username
|
||||||
|
&& !password;
|
||||||
|
}
|
||||||
|
|
||||||
addActionHandler('validateRequestedInfo', (global, actions, payload): ActionReturnType => {
|
addActionHandler('validateRequestedInfo', (global, actions, payload): ActionReturnType => {
|
||||||
const { requestInfo, saveInfo, tabId = getCurrentTabId() } = payload;
|
const { requestInfo, saveInfo, tabId = getCurrentTabId() } = payload;
|
||||||
@ -429,8 +454,7 @@ async function sendSmartGlocalCredentials<T extends GlobalState>(
|
|||||||
url = 'https://tgb.smart-glocal.com/cds/v1/tokenize/card';
|
url = 'https://tgb.smart-glocal.com/cds/v1/tokenize/card';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokenizeUrl?.startsWith('https://')
|
if (tokenizeUrl && isValidSmartGlocalTokenizeUrl(tokenizeUrl)) {
|
||||||
&& tokenizeUrl.endsWith('.smart-glocal.com/cds/v1/tokenize/card')) {
|
|
||||||
url = tokenizeUrl;
|
url = tokenizeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -239,14 +239,14 @@ interface WebAppOutboundEventMap {
|
|||||||
location_checked:
|
location_checked:
|
||||||
| { available: false }
|
| { available: false }
|
||||||
| {
|
| {
|
||||||
available: boolean;
|
available: true;
|
||||||
access_requested: boolean;
|
access_requested: boolean;
|
||||||
access_granted?: boolean;
|
access_granted?: boolean;
|
||||||
};
|
};
|
||||||
location_requested:
|
location_requested:
|
||||||
| { available: boolean }
|
| { available: false }
|
||||||
| {
|
| {
|
||||||
available: boolean;
|
available: true;
|
||||||
latitude: number;
|
latitude: number;
|
||||||
longitude: number;
|
longitude: number;
|
||||||
altitude: number | null;
|
altitude: number | null;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user