Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Call showOauthClientsLimitExceeded only when Cookie exists #956

Merged
merged 3 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions src/components/webviews/CozyProxyWebView.functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { Platform } from 'react-native'

import Minilog from 'cozy-minilog'

import { checkOauthClientsLimit } from '/app/domain/limits/checkOauthClientsLimit'
import { showOauthClientsLimitExceeded } from '/app/domain/limits/OauthClientsLimitService'
import { IndexInjectionWebviewComponent } from '/components/webviews/webViewComponents/IndexInjectionWebviewComponent'
import { updateCozyAppBundleInBackground } from '/libs/cozyAppBundle/cozyAppBundle'
import { getCookie } from '/libs/httpserver/httpCookieManager'

const log = Minilog('CozyProxyWebView.functions')

const NO_INJECTED_HTML = 'NO_INJECTED_HTML'

export const initHtmlContent = async ({
httpServerContext,
slug,
href,
client,
dispatch,
setHtmlContentCreationDate
}) => {
const cookieAlreadyExists = (await getCookie(client)) !== undefined
log.debug(`Check cookie already exists: ${cookieAlreadyExists}`)

if (
cookieAlreadyExists &&
(await doesOauthClientsLimitPreventsLoading(client, slug, href))
) {
log.debug('Stop loading HTML because OAuth client limit is reached (pre)')
return
}

const htmlContent = await httpServerContext.getIndexHtmlForSlug(slug, client)

if (
!cookieAlreadyExists &&
(await doesOauthClientsLimitPreventsLoading(client, slug, href))
) {
log.debug('Stop loading HTML because OAuth client limit is reached (post)')
return
}

const { source: sourceActual, nativeConfig: nativeConfigActual } =
getPlaformSpecificConfig(href, htmlContent || NO_INJECTED_HTML)

setHtmlContentCreationDate(Date.now())
dispatch(oldState => ({
...oldState,
html: htmlContent,
nativeConfig: nativeConfigActual,
source: sourceActual
}))

updateCozyAppBundleInBackground({
slug,
client
})
}

const getHttpUnsecureUrl = uri => {
if (uri) {
let httpUnsecureUrl = new URL(uri)
httpUnsecureUrl.protocol = 'http:'

return httpUnsecureUrl
}

return uri
}

/**
* Retrieve the WebView's configuration for the current platform
*
* Android is not compatible with html/baseUrl injection as history would be broken
*
* So html/baseUrl injection is done only on iOS
*
* Instead, Android version is based on native WebView's ability to intercept queries
* and override the result. In this case we should use uri instead of html/baseUrl and
* declare a nativeConfig with IndexInjectionWebviewComponent
*
* @param {string} uri - the webView's URI
* @param {string} html - the HTML to inject as index.html
* @returns source and nativeConfig props to be set on the WebView
*/
const getPlaformSpecificConfig = (uri, html) => {
const httpUnsecureUrl = getHttpUnsecureUrl(uri)

if (html === NO_INJECTED_HTML) {
return {
source: { uri },
nativeConfig: undefined
}
}

const source =
Platform.OS === 'ios'
? { html, baseUrl: httpUnsecureUrl.toString() }
: { uri }

const nativeConfig =
Platform.OS === 'ios'
? undefined
: { component: IndexInjectionWebviewComponent }

return {
source,
nativeConfig
}
}

/**
* Checks if OauthClientLimit is reached and trigger the OauthClientsLimitExceeded limit if needed
* Also check if the WebView rendering should be prevented and returns the result
*
* @param {CozyClient} client - CozyClient instance
* @param {string} slug - The application slug
* @param {string} href - The WebView requested href
* @returns true if the WebView rendering should be prevented, false otherwise
*/
const doesOauthClientsLimitPreventsLoading = async (client, slug, href) => {
const isOauthClientsLimitExeeded = await checkOauthClientsLimit(client)

if (isOauthClientsLimitExeeded) {
if (slug === 'home') {
showOauthClientsLimitExceeded(href)
return false
} else if (slug !== 'settings') {
showOauthClientsLimitExceeded(href)
return true
}
}

return false
}
107 changes: 6 additions & 101 deletions src/components/webviews/CozyProxyWebView.js
Original file line number Diff line number Diff line change
@@ -1,116 +1,21 @@
import Minilog from 'cozy-minilog'
import { useFocusEffect } from '@react-navigation/native'
import React, { useCallback, useState, useEffect } from 'react'
import { AppState, Platform, View } from 'react-native'
import { AppState, View } from 'react-native'

import { useClient } from 'cozy-client'
import Minilog from 'cozy-minilog'

import { styles } from './CozyProxyWebView.styles'
import { CozyWebView } from './CozyWebView'

import { checkOauthClientsLimit } from '/app/domain/limits/checkOauthClientsLimit'
import { showOauthClientsLimitExceeded } from '/app/domain/limits/OauthClientsLimitService'
import { RemountProgress } from '/app/view/Loading/RemountProgress'
import { updateCozyAppBundleInBackground } from '/libs/cozyAppBundle/cozyAppBundle'
import { initHtmlContent } from '/components/webviews/CozyProxyWebView.functions'
import { CozyWebView } from '/components/webviews/CozyWebView'
import { useHttpServerContext } from '/libs/httpserver/httpServerProvider'
import { IndexInjectionWebviewComponent } from '/components/webviews/webViewComponents/IndexInjectionWebviewComponent'

const log = Minilog('CozyProxyWebView')
import { styles } from '/components/webviews/CozyProxyWebView.styles'

const NO_INJECTED_HTML = 'NO_INJECTED_HTML'
const log = Minilog('CozyProxyWebView')

const HTML_CONTENT_EXPIRATION_DELAY_IN_MS = 23 * 60 * 60 * 1000

const getHttpUnsecureUrl = uri => {
if (uri) {
let httpUnsecureUrl = new URL(uri)
httpUnsecureUrl.protocol = 'http:'

return httpUnsecureUrl
}

return uri
}

/**
* Retrieve the WebView's configuration for the current platform
*
* Android is not compatible with html/baseUrl injection as history would be broken
*
* So html/baseUrl injection is done only on iOS
*
* Instead, Android version is based on native WebView's ability to intercept queries
* and override the result. In this case we should use uri instead of html/baseUrl and
* declare a nativeConfig with IndexInjectionWebviewComponent
*
* @param {string} uri - the webView's URI
* @param {string} html - the HTML to inject as index.html
* @returns source and nativeConfig props to be set on the WebView
*/
const getPlaformSpecificConfig = (uri, html) => {
const httpUnsecureUrl = getHttpUnsecureUrl(uri)

if (html === NO_INJECTED_HTML) {
return {
source: { uri },
nativeConfig: undefined
}
}

const source =
Platform.OS === 'ios'
? { html, baseUrl: httpUnsecureUrl.toString() }
: { uri }

const nativeConfig =
Platform.OS === 'ios'
? undefined
: { component: IndexInjectionWebviewComponent }

return {
source,
nativeConfig
}
}

const initHtmlContent = async ({
httpServerContext,
slug,
href,
client,
dispatch,
setHtmlContentCreationDate
}) => {
const isOauthClientsLimitExeeded = await checkOauthClientsLimit(client)

if (isOauthClientsLimitExeeded) {
if (slug === 'home') {
showOauthClientsLimitExceeded(href)
} else if (slug !== 'settings') {
showOauthClientsLimitExceeded(href)
return
}
}

const htmlContent = await httpServerContext.getIndexHtmlForSlug(slug, client)

const { source: sourceActual, nativeConfig: nativeConfigActual } =
getPlaformSpecificConfig(href, htmlContent || NO_INJECTED_HTML)

setHtmlContentCreationDate(Date.now())
dispatch(oldState => ({
...oldState,
html: htmlContent,
nativeConfig: nativeConfigActual,
source: sourceActual
}))

updateCozyAppBundleInBackground({
slug,
client
})
}

export const CozyProxyWebView = ({
slug,
href,
Expand Down
Loading
Loading