Support for creator-requested geoblocking (#1063)
Attempt to fix logic + case Fix logic Co-authored-by: Thomas Zarebczan <thomas.zarebczan@gmail.com>
This commit is contained in:
parent
d52fd8e26e
commit
ca7b98ecf5
7 changed files with 94 additions and 3 deletions
|
@ -120,7 +120,7 @@ ENABLE_WILD_WEST=true
|
|||
BRANDED_SITE=odysee
|
||||
LOADING_BAR_COLOR=#e50054
|
||||
|
||||
# FIREBASE
|
||||
# --- Firebase ---
|
||||
FIREBASE_API_KEY=AIzaSyAgc-4QORyglpYZ3qH9E5pDauEDOJXgM3A
|
||||
FIREBASE_AUTH_DOMAIN=lbry-mobile.firebaseapp.com
|
||||
FIREBASE_PROJECT_ID=lbry-mobile
|
||||
|
@ -130,6 +130,13 @@ FIREBASE_APP_ID=1:638894153788:web:35b295b15297201bd2e339
|
|||
FIREBASE_MEASUREMENT_ID=G-2MPJGFEEXC
|
||||
FIREBASE_VAPID_KEY=BFayEBpwMTU9GQQpXgitIJkfx-SD8-ltrFb3wLTZWgA27MfBhG4948pe0eERl432NzPrMKsbkXnA7ap_vLPgLYk
|
||||
|
||||
# Development
|
||||
# --- Geoblock ---
|
||||
# Note: our current version of dotenv doesn't support multiline definition.
|
||||
#
|
||||
# FORMAT: "<channel_id>; type=[livestream|video|*]; country=[xx|*]; continent=[xx|*]; | ..."
|
||||
#
|
||||
GEOBLOCKED_CHANNELS="148bfcb49da2c2e781ae27387e45043a4bcbd51e; types=livestream; countries=FR,MS; continents=AF,EU; | 636098f86be74be8b609c38e643e48786d58f413; types=livestream,video; countries=EU,SA; continents=EU;"
|
||||
|
||||
# --- Development ---
|
||||
REPORT_NEW_STRINGS=false
|
||||
USE_LOCAL_HOMEPAGE_DATA=false
|
||||
|
|
24
config.js
24
config.js
|
@ -90,6 +90,30 @@ const config = {
|
|||
AD_KEYWORD_BLOCKLIST_CHECK_DESCRIPTION: process.env.AD_KEYWORD_BLOCKLIST_CHECK_DESCRIPTION,
|
||||
};
|
||||
|
||||
config.GEOBLOCKED_CHANNELS = {};
|
||||
if (process.env.GEOBLOCKED_CHANNELS) {
|
||||
const entries = process.env.GEOBLOCKED_CHANNELS.split('|');
|
||||
|
||||
entries.forEach((entry) => {
|
||||
const fields = entry.split(';');
|
||||
|
||||
if (fields.length > 0) {
|
||||
const channelId = fields[0].trim();
|
||||
config.GEOBLOCKED_CHANNELS[channelId] = {};
|
||||
|
||||
for (let i = 1; i < fields.length; ++i) {
|
||||
const kv = fields[i].split('=');
|
||||
|
||||
if (kv.length === 2) {
|
||||
const key = kv[0].trim();
|
||||
const values = kv[1].trim();
|
||||
config.GEOBLOCKED_CHANNELS[channelId][key] = values.split(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
config.SDK_API_PATH = `${config.LBRY_WEB_API}/api/v1`;
|
||||
config.PROXY_URL = `${config.SDK_API_PATH}/proxy`;
|
||||
|
||||
|
|
13
flow-typed/user.js
vendored
13
flow-typed/user.js
vendored
|
@ -34,3 +34,16 @@ declare type User = {
|
|||
global_mod: boolean,
|
||||
odyseeMembershipsPerClaimIds: ?{},
|
||||
};
|
||||
|
||||
declare type LocaleInfo = {
|
||||
continent: string,
|
||||
country: string,
|
||||
gdpr_required: boolean,
|
||||
is_eu_member: boolean,
|
||||
};
|
||||
|
||||
declare type GeoBlock = {
|
||||
types: Array<string>,
|
||||
countries: Array<string>,
|
||||
continents: Array<string>,
|
||||
};
|
||||
|
|
|
@ -2218,6 +2218,7 @@
|
|||
"The minimum duration must not exceed Feb 8th, 2022.": "The minimum duration must not exceed Feb 8th, 2022.",
|
||||
"No limit": "No limit",
|
||||
"Search results are being filtered by language. Click here to change the setting.": "Search results are being filtered by language. Click here to change the setting.",
|
||||
"This creator has requested that their livestream be blocked in your region.": "This creator has requested that their livestream be blocked in your region.",
|
||||
"There are language translations available for your location! Do you want to switch from English?": "There are language translations available for your location! Do you want to switch from English?",
|
||||
"A homepage and language translations are available for your location! Do you want to switch?": "A homepage and language translations are available for your location! Do you want to switch?",
|
||||
"A homepage is available for your location! Do you want to switch?": "A homepage is available for your location! Do you want to switch?",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import React, { useEffect, useRef, useState, useLayoutEffect } from 'react';
|
||||
import { lazyImport } from 'util/lazyImport';
|
||||
import { tusUnlockAndNotify, tusHandleTabUpdates } from 'util/tus';
|
||||
|
@ -364,6 +365,17 @@ function App(props: Props) {
|
|||
}
|
||||
}, [previousRewardApproved, isRewardApproved]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchLocaleApi().then((response) => {
|
||||
const locale: LocaleInfo = response?.data;
|
||||
if (locale) {
|
||||
// Put in 'window' for now. Can be moved to localStorage or wherever,
|
||||
// but the key should remain the same so clients are not affected.
|
||||
window[SETTINGS.LOCALE] = locale;
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Load IMA3 SDK for aniview
|
||||
// useEffect(() => {
|
||||
// if (!isAuthenticated && SHOW_ADS) {
|
||||
|
|
|
@ -40,6 +40,7 @@ export const SUPPORT_OPTION = 'support_option';
|
|||
export const TILE_LAYOUT = 'tile_layout';
|
||||
export const VIDEO_THEATER_MODE = 'video_theater_mode';
|
||||
export const VIDEO_PLAYBACK_RATE = 'video_playback_rate';
|
||||
export const LOCALE = 'odysee_user_locale';
|
||||
|
||||
export const SETTINGS_GRP = {
|
||||
APPEARANCE: 'appearance',
|
||||
|
|
|
@ -6,11 +6,32 @@ import analytics from 'analytics';
|
|||
import LivestreamLayout from 'component/livestreamLayout';
|
||||
import moment from 'moment';
|
||||
import Page from 'component/page';
|
||||
import Yrbl from 'component/yrbl';
|
||||
import { GEOBLOCKED_CHANNELS } from 'config';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import React from 'react';
|
||||
import { useIsMobile } from 'effects/use-screensize';
|
||||
|
||||
const LivestreamChatLayout = lazyImport(() => import('component/livestreamChatLayout' /* webpackChunkName: "chat" */));
|
||||
|
||||
function isLivestreamGeoAllowed(channelId: ?string, isLive: boolean) {
|
||||
const locale: LocaleInfo = window[SETTINGS.LOCALE];
|
||||
const geoBlock: GeoBlock = GEOBLOCKED_CHANNELS[channelId];
|
||||
|
||||
if (locale && geoBlock) {
|
||||
const typeBlocked = geoBlock.types && geoBlock.types.includes('livestream');
|
||||
const countryBlocked = geoBlock.countries && geoBlock.countries.includes(locale.country);
|
||||
const europeanUnionOnly = geoBlock.continents && geoBlock.continents.includes('EU-UNION') && locale.is_eu_member;
|
||||
const continentBlocked =
|
||||
europeanUnionOnly || (geoBlock.continents && geoBlock.continents.includes(locale.continent));
|
||||
|
||||
return typeBlocked && !countryBlocked && !continentBlocked;
|
||||
}
|
||||
|
||||
// If 'locale/get' fails, we don't know whether to block or not. Flaw?
|
||||
return true;
|
||||
}
|
||||
|
||||
type Props = {
|
||||
activeLivestreamForChannel: any,
|
||||
activeLivestreamInitialized: boolean,
|
||||
|
@ -54,6 +75,7 @@ export default function LivestreamPage(props: Props) {
|
|||
const claimId = claim && claim.claim_id;
|
||||
const isCurrentClaimLive = isChannelBroadcasting && activeLivestreamForChannel.claimId === claimId;
|
||||
const livestreamChannelId = channelClaimId || '';
|
||||
const isGeoBlocked = !isLivestreamGeoAllowed(channelClaimId, isCurrentClaimLive);
|
||||
|
||||
// $FlowFixMe
|
||||
const release = moment.unix(claim.value.release_time);
|
||||
|
@ -160,6 +182,7 @@ export default function LivestreamPage(props: Props) {
|
|||
livestream
|
||||
chatDisabled={hideComments}
|
||||
rightSide={
|
||||
!isGeoBlocked &&
|
||||
!hideComments &&
|
||||
isInitialized && (
|
||||
<React.Suspense fallback={null}>
|
||||
|
@ -168,7 +191,17 @@ export default function LivestreamPage(props: Props) {
|
|||
)
|
||||
}
|
||||
>
|
||||
{isInitialized && (
|
||||
{isGeoBlocked && (
|
||||
<div className="main--empty">
|
||||
<Yrbl
|
||||
title={__('This creator has requested that their livestream be blocked in your region.')}
|
||||
type="sad"
|
||||
alwaysShow
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isInitialized && !isGeoBlocked && (
|
||||
<LivestreamLayout
|
||||
uri={uri}
|
||||
hideComments={hideComments}
|
||||
|
|
Loading…
Reference in a new issue