From 34863a67a32d454b9c340d90e590f580be0b7130 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Mon, 20 Mar 2023 05:26:48 -0700 Subject: [PATCH 1/7] apply suggested fix for activity restore crash --- .../android/app/src/main/java/com/databag/MainActivity.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/mobile/android/app/src/main/java/com/databag/MainActivity.java b/app/mobile/android/app/src/main/java/com/databag/MainActivity.java index 1d66b543..57a40a9f 100644 --- a/app/mobile/android/app/src/main/java/com/databag/MainActivity.java +++ b/app/mobile/android/app/src/main/java/com/databag/MainActivity.java @@ -16,6 +16,11 @@ public class MainActivity extends ReactActivity { return "Databag"; } + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(null); + } + /** * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React From 46e76f7b7606d1ed6fe9f58459972dc49df95522 Mon Sep 17 00:00:00 2001 From: balzack Date: Mon, 20 Mar 2023 10:04:59 -0700 Subject: [PATCH 2/7] added missing import --- .../android/app/src/main/java/com/databag/MainActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/mobile/android/app/src/main/java/com/databag/MainActivity.java b/app/mobile/android/app/src/main/java/com/databag/MainActivity.java index 57a40a9f..711be362 100644 --- a/app/mobile/android/app/src/main/java/com/databag/MainActivity.java +++ b/app/mobile/android/app/src/main/java/com/databag/MainActivity.java @@ -1,5 +1,6 @@ package com.databag; +import android.os.Bundle; import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; From dc8c5357934cb1c8cb0f2776b05039051f176a50 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Sun, 2 Apr 2023 22:21:10 -0700 Subject: [PATCH 3/7] adding clickable links to webapp --- net/web/package.json | 1 + .../conversation/topicItem/TopicItem.jsx | 3 ++- .../conversation/useConversation.hook.js | 25 +++++++++++++++++-- net/web/yarn.lock | 5 ++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/net/web/package.json b/net/web/package.json index 80105d88..b5234af5 100644 --- a/net/web/package.json +++ b/net/web/package.json @@ -22,6 +22,7 @@ "axios": "^0.27.2", "base-64": "^1.0.0", "crypto-js": "^4.1.1", + "dompurify": "^3.0.1", "jsencrypt": "^2.3.1", "react": "^18.2.0", "react-color": "^2.19.3", diff --git a/net/web/src/session/conversation/topicItem/TopicItem.jsx b/net/web/src/session/conversation/topicItem/TopicItem.jsx index df85f839..4ab16f06 100644 --- a/net/web/src/session/conversation/topicItem/TopicItem.jsx +++ b/net/web/src/session/conversation/topicItem/TopicItem.jsx @@ -7,6 +7,7 @@ import { Space, Skeleton, Button, Modal, Input } from 'antd'; import { ExclamationCircleOutlined, DeleteOutlined, EditOutlined, FireOutlined, PictureOutlined } from '@ant-design/icons'; import { Carousel } from 'carousel/Carousel'; import { useTopicItem } from './useTopicItem.hook'; +import * as DOMPurify from 'dompurify'; export function TopicItem({ host, sealed, topic, update, remove }) { @@ -123,7 +124,7 @@ export function TopicItem({ host, sealed, topic, update, remove }) { )} { !sealed && !state.editing && (
-
{ topic.text }
+
)} { state.editing && ( diff --git a/net/web/src/session/conversation/useConversation.hook.js b/net/web/src/session/conversation/useConversation.hook.js index 02c16da5..58f84f89 100644 --- a/net/web/src/session/conversation/useConversation.hook.js +++ b/net/web/src/session/conversation/useConversation.hook.js @@ -132,6 +132,27 @@ export function useConversation(cardId, channelId) { // eslint-disable-next-line }, [state.contentKey]); + const clickableText = (text) => { + var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name + '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path + '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string + '(\\#[-a-z\\d_]*)?$','i'); // fragment locator + + let clickable = ''; + const words = text == null ? '' : text.split(' '); + words.forEach(word => { + if (!!pattern.test(word)) { + clickable += `${word} `; + } + else { + clickable += `${word} `; + } + }) + return `

${clickable}

`; + }; + const syncTopic = (item, value) => { const revision = value.data?.detailRevision; const detail = value.data?.topicDetail || {}; @@ -189,14 +210,14 @@ export function useConversation(cardId, channelId) { if (detail.dataType === 'superbasictopic') { const message = JSON.parse(detail.data); item.assets = message.assets; - item.text = message.text; + item.text = clickableText(message.text); item.textColor = message.textColor ? message.textColor : '#444444'; item.textSize = message.textSize ? message.textSize : 14; } if (detail.dataType === 'sealedtopic' && state.contentKey) { const subject = decryptTopicSubject(detail.data, state.contentKey); item.assets = subject.message.assets; - item.text = subject.message.text; + item.text = clickableText(subject.message.text); item.textColor = subject.message.textColor ? subject.message.textColor : '#444444'; item.textSize = subject.message.textSize ? subject.message.textSize : 14; } diff --git a/net/web/yarn.lock b/net/web/yarn.lock index 70453493..09c19758 100644 --- a/net/web/yarn.lock +++ b/net/web/yarn.lock @@ -4366,6 +4366,11 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: dependencies: domelementtype "^2.2.0" +dompurify@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.1.tgz#a0933f38931b3238934dd632043b727e53004289" + integrity sha512-60tsgvPKwItxZZdfLmamp0MTcecCta3avOhsLgPZ0qcWt96OasFfhkeIRbJ6br5i0fQawT1/RBGB5L58/Jpwuw== + domutils@^1.7.0: version "1.7.0" resolved "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz" From 9f5647fa57d583789274be1fe4b97d155e17c14b Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Mon, 3 Apr 2023 11:00:09 -0700 Subject: [PATCH 4/7] adding clickable urls in mobile --- .../ios/Databag.xcodeproj/project.pbxproj | 8 ++--- .../conversation/topicItem/TopicItem.jsx | 8 ++--- .../topicItem/useTopicItem.hook.js | 33 +++++++++++++++++-- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/app/mobile/ios/Databag.xcodeproj/project.pbxproj b/app/mobile/ios/Databag.xcodeproj/project.pbxproj index 5761ce0e..c36d2958 100644 --- a/app/mobile/ios/Databag.xcodeproj/project.pbxproj +++ b/app/mobile/ios/Databag.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 46D8108CBA031189090AFC14 /* Pods_Databag_DatabagTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1181227D40684F18A9414840 /* Pods_Databag_DatabagTests.framework */; }; 7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B13A773299E21170048D0DD /* GoogleService-Info.plist */; }; - 7B6135A329B439B80094A6E7 /* login.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B6135A229B439B80094A6E7 /* login.png */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; A0B1EC4533FCFC5940B5FD7F /* Pods_Databag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9462C028F47F083241BB7941 /* Pods_Databag.framework */; }; /* End PBXBuildFile section */ @@ -43,7 +42,6 @@ 5709B34CF0A7D63546082F79 /* Pods-Databag.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag.release.xcconfig"; path = "Target Support Files/Pods-Databag/Pods-Databag.release.xcconfig"; sourceTree = ""; }; 5B7EB9410499542E8C5724F5 /* Pods-Databag-DatabagTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag-DatabagTests.debug.xcconfig"; path = "Target Support Files/Pods-Databag-DatabagTests/Pods-Databag-DatabagTests.debug.xcconfig"; sourceTree = ""; }; 7B13A773299E21170048D0DD /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; - 7B6135A229B439B80094A6E7 /* login.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = login.png; sourceTree = ""; }; 7B6135A429B68A7B0094A6E7 /* Databag.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Databag.entitlements; path = Databag/Databag.entitlements; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = Databag/LaunchScreen.storyboard; sourceTree = ""; }; 89C6BE57DB24E9ADA2F236DE /* Pods-Databag-DatabagTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag-DatabagTests.release.xcconfig"; path = "Target Support Files/Pods-Databag-DatabagTests/Pods-Databag-DatabagTests.release.xcconfig"; sourceTree = ""; }; @@ -97,7 +95,6 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */, 13B07FB61A68108700A75B9A /* Info.plist */, 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, - 7B6135A229B439B80094A6E7 /* login.png */, 13B07FB71A68108700A75B9A /* main.m */, ); name = Databag; @@ -253,7 +250,6 @@ buildActionMask = 2147483647; files = ( 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, - 7B6135A329B439B80094A6E7 /* login.png in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */, ); @@ -575,7 +571,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -647,7 +643,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; diff --git a/app/mobile/src/session/conversation/topicItem/TopicItem.jsx b/app/mobile/src/session/conversation/topicItem/TopicItem.jsx index eed90eb5..d590eaf7 100644 --- a/app/mobile/src/session/conversation/topicItem/TopicItem.jsx +++ b/app/mobile/src/session/conversation/topicItem/TopicItem.jsx @@ -131,8 +131,8 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block return ( - - + + { state.logo !== 'avatar' && state.logo && ( )} @@ -141,7 +141,7 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block )} { state.name } { state.timestamp } - + { state.status === 'confirmed' && ( <> { state.transform === 'complete' && state.assets && ( @@ -175,7 +175,7 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block )} - + { focused && ( { state.editable && ( diff --git a/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js b/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js index f2330a4c..7be7e10a 100644 --- a/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js +++ b/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js @@ -1,13 +1,15 @@ import { useState, useEffect, useContext } from 'react'; +import { Linking } from 'react-native'; import { ConversationContext } from 'context/ConversationContext'; import { CardContext } from 'context/CardContext'; import { ProfileContext } from 'context/ProfileContext'; import { AccountContext } from 'context/AccountContext'; import moment from 'moment'; -import { useWindowDimensions } from 'react-native'; +import { useWindowDimensions, Text } from 'react-native'; import Colors from 'constants/Colors'; import { getCardByGuid } from 'context/cardUtil'; import { decryptTopicSubject } from 'context/sealUtil'; +import * as DOMPurify from 'dompurify'; export function useTopicItem(item, hosting, remove, contentKey) { @@ -95,7 +97,7 @@ export function useTopicItem(item, hosting, remove, contentKey) { try { sealed = false; parsed = JSON.parse(data); - message = parsed.text; + message = clickableText(parsed.text); assets = parsed.assets; if (parsed.textSize === 'small') { fontSize = 10; @@ -138,7 +140,7 @@ export function useTopicItem(item, hosting, remove, contentKey) { if (unsealed) { sealed = false; parsed = unsealed.message; - message = parsed?.text; + message = clickableText(parsed?.text); if (parsed?.textSize === 'small') { fontSize = 10; } @@ -194,6 +196,31 @@ export function useTopicItem(item, hosting, remove, contentKey) { } }; + const clickableText = (text) => { + var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name + '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path + '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string + '(\\#[-a-z\\d_]*)?$','i'); // fragment locator + + let clickable = []; + let group = ''; + const words = text == null ? '' : text.split(' '); + words.forEach((word, index) => { + if (!!pattern.test(word)) { + clickable.push({ group }); + group = ''; + clickable.push( Linking.openURL(word)} style={{ fontStyle: 'italic' }}>{ word + ' ' }); + } + else { + group += `${word} `; + } + }) + clickable.push({ group }); + return { clickable }; + }; + const actions = { showCarousel: (index) => { updateState({ carousel: true, carouselIndex: index }); From 37f6ec6f09507a014d25be39d94b912d2f448e9e Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Mon, 3 Apr 2023 11:51:18 -0700 Subject: [PATCH 5/7] avoid use of dangerously --- .../conversation/topicItem/TopicItem.jsx | 4 ++-- .../topicItem/useTopicItem.hook.js | 13 +++++++---- .../conversation/topicItem/TopicItem.jsx | 3 +-- .../conversation/useConversation.hook.js | 23 ++++++++++++------- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/app/mobile/src/session/conversation/topicItem/TopicItem.jsx b/app/mobile/src/session/conversation/topicItem/TopicItem.jsx index d590eaf7..46bccc1c 100644 --- a/app/mobile/src/session/conversation/topicItem/TopicItem.jsx +++ b/app/mobile/src/session/conversation/topicItem/TopicItem.jsx @@ -162,8 +162,8 @@ export function TopicItem({ item, focused, focus, hosting, remove, update, block )} - { state.message && !state.sealed && ( - { state.message } + { state.clickable && !state.sealed && ( + { state.clickable } )} { state.sealed && ( sealed message diff --git a/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js b/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js index 7be7e10a..d3b5b4a1 100644 --- a/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js +++ b/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js @@ -20,6 +20,7 @@ export function useTopicItem(item, hosting, remove, contentKey) { logo: null, timestamp: null, message: null, + clickable: null, carousel: false, carouselIndex: 0, width: null, @@ -92,12 +93,13 @@ export function useTopicItem(item, hosting, remove, contentKey) { } } - let parsed, sealed, message, assets, fontSize, fontColor; + let parsed, sealed, message, clickable, assets, fontSize, fontColor; if (dataType === 'superbasictopic') { try { sealed = false; parsed = JSON.parse(data); - message = clickableText(parsed.text); + message = parsed?.text; + clickable = clickableText(parsed.text); assets = parsed.assets; if (parsed.textSize === 'small') { fontSize = 10; @@ -140,7 +142,8 @@ export function useTopicItem(item, hosting, remove, contentKey) { if (unsealed) { sealed = false; parsed = unsealed.message; - message = clickableText(parsed?.text); + message = parsed?.text; + clickable = clickableText(parsed?.text); if (parsed?.textSize === 'small') { fontSize = 10; } @@ -179,7 +182,7 @@ export function useTopicItem(item, hosting, remove, contentKey) { const editable = guid === identity?.guid && parsed; const deletable = editable || hosting; - updateState({ logo, name, nameSet, known, sealed, message, fontSize, fontColor, timestamp, transform, status, assets, deletable, editable, editData: parsed, editMessage: message, editType: dataType }); + updateState({ logo, name, nameSet, known, sealed, message, clickable, fontSize, fontColor, timestamp, transform, status, assets, deletable, editable, editData: parsed, editMessage: message, editType: dataType }); }, [conversation.state, card.state, account.state, item, contentKey]); const unsealTopic = async (topicId, revision, topicDetail) => { @@ -206,7 +209,7 @@ export function useTopicItem(item, hosting, remove, contentKey) { let clickable = []; let group = ''; - const words = text == null ? '' : text.split(' '); + const words = text == null ? [''] : text.split(' '); words.forEach((word, index) => { if (!!pattern.test(word)) { clickable.push({ group }); diff --git a/net/web/src/session/conversation/topicItem/TopicItem.jsx b/net/web/src/session/conversation/topicItem/TopicItem.jsx index 4ab16f06..0136eb9b 100644 --- a/net/web/src/session/conversation/topicItem/TopicItem.jsx +++ b/net/web/src/session/conversation/topicItem/TopicItem.jsx @@ -7,7 +7,6 @@ import { Space, Skeleton, Button, Modal, Input } from 'antd'; import { ExclamationCircleOutlined, DeleteOutlined, EditOutlined, FireOutlined, PictureOutlined } from '@ant-design/icons'; import { Carousel } from 'carousel/Carousel'; import { useTopicItem } from './useTopicItem.hook'; -import * as DOMPurify from 'dompurify'; export function TopicItem({ host, sealed, topic, update, remove }) { @@ -124,7 +123,7 @@ export function TopicItem({ host, sealed, topic, update, remove }) { )} { !sealed && !state.editing && (
-
+
{ topic.clickable }
)} { state.editing && ( diff --git a/net/web/src/session/conversation/useConversation.hook.js b/net/web/src/session/conversation/useConversation.hook.js index 58f84f89..ff1608b4 100644 --- a/net/web/src/session/conversation/useConversation.hook.js +++ b/net/web/src/session/conversation/useConversation.hook.js @@ -9,6 +9,7 @@ import { ProfileContext } from 'context/ProfileContext'; import { isUnsealed, getChannelSeals, getContentKey, encryptTopicSubject } from 'context/sealUtil'; import { decryptTopicSubject } from 'context/sealUtil'; import { getProfileByGuid } from 'context/cardUtil'; +import * as DOMPurify from 'dompurify'; export function useConversation(cardId, channelId) { @@ -140,17 +141,21 @@ export function useConversation(cardId, channelId) { '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string '(\\#[-a-z\\d_]*)?$','i'); // fragment locator - let clickable = ''; - const words = text == null ? '' : text.split(' '); - words.forEach(word => { + let group = ''; + let clickable = []; + const words = text == null ? '' : DOMPurify.sanitize(text).split(' '); + words.forEach((word, index) => { if (!!pattern.test(word)) { - clickable += `${word} `; + clickable.push({ group }); + group = ''; + clickable.push({ `${word} ` }); } else { - clickable += `${word} `; + group += `${word} `; } }) - return `

${clickable}

`; + clickable.push({ group }); + return

{ clickable }

; }; const syncTopic = (item, value) => { @@ -210,14 +215,16 @@ export function useConversation(cardId, channelId) { if (detail.dataType === 'superbasictopic') { const message = JSON.parse(detail.data); item.assets = message.assets; - item.text = clickableText(message.text); + item.text = message.text; + item.clickable = clickableText(message.text); item.textColor = message.textColor ? message.textColor : '#444444'; item.textSize = message.textSize ? message.textSize : 14; } if (detail.dataType === 'sealedtopic' && state.contentKey) { const subject = decryptTopicSubject(detail.data, state.contentKey); item.assets = subject.message.assets; - item.text = clickableText(subject.message.text); + item.text = subject.message.text; + item.clickable = clickableText(subject.message.text); item.textColor = subject.message.textColor ? subject.message.textColor : '#444444'; item.textSize = subject.message.textSize ? subject.message.textSize : 14; } From b0b5c1975411449c333195a934be3f12bb29cebf Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Mon, 3 Apr 2023 12:06:07 -0700 Subject: [PATCH 6/7] removing tos from ios --- app/mobile/src/access/admin/Admin.jsx | 34 ++++++++++++----------- app/mobile/src/access/create/Create.jsx | 34 ++++++++++++----------- app/mobile/src/access/login/Login.jsx | 36 +++++++++++++------------ app/mobile/src/access/reset/Reset.jsx | 36 +++++++++++++------------ 4 files changed, 74 insertions(+), 66 deletions(-) diff --git a/app/mobile/src/access/admin/Admin.jsx b/app/mobile/src/access/admin/Admin.jsx index 9e5fc68f..09fef349 100644 --- a/app/mobile/src/access/admin/Admin.jsx +++ b/app/mobile/src/access/admin/Admin.jsx @@ -56,22 +56,24 @@ export function Admin() { - - - View Terms of Service - - actions.agree(!state.agree)}> - { state.agree && ( - - )} - { !state.agree && ( - - )} - I agree to Terms of Service - - + { Platform.OS !== 'ios' && ( + + + View Terms of Service + + actions.agree(!state.agree)}> + { state.agree && ( + + )} + { !state.agree && ( + + )} + I agree to Terms of Service + + + )} - { state.enabled && state.agree && ( + { state.enabled && (Platform.OS === 'ios' || state.agree) && ( { state.busy && ( @@ -81,7 +83,7 @@ export function Admin() { )} )} - { (!state.enabled || !state.agree) && ( + { (!state.enabled || (Platform.OS !== 'ios' && !state.agree)) && ( Access diff --git a/app/mobile/src/access/create/Create.jsx b/app/mobile/src/access/create/Create.jsx index 43e426ff..afe5ff1e 100644 --- a/app/mobile/src/access/create/Create.jsx +++ b/app/mobile/src/access/create/Create.jsx @@ -138,23 +138,25 @@ export function Create() { )} - - - View Terms of Service - - actions.agree(!state.agree)}> - { state.agree && ( - - )} - { !state.agree && ( - - )} - I agree to Terms of Service - - + { Platform.OS !== 'ios' && ( + + + View Terms of Service + + actions.agree(!state.agree)}> + { state.agree && ( + + )} + { !state.agree && ( + + )} + I agree to Terms of Service + + + )} - { state.enabled && state.agree && ( + { state.enabled && (Platform.OS === 'ios' || state.agree) && ( { state.busy && ( @@ -164,7 +166,7 @@ export function Create() { )} )} - { (!state.enabled || !state.agree) && ( + { (!state.enabled || (Platform.OS !== 'ios' && !state.agree)) && ( Create Account diff --git a/app/mobile/src/access/login/Login.jsx b/app/mobile/src/access/login/Login.jsx index cc1f6028..78793513 100644 --- a/app/mobile/src/access/login/Login.jsx +++ b/app/mobile/src/access/login/Login.jsx @@ -1,4 +1,4 @@ -import { KeyboardAvoidingView, ActivityIndicator, Modal, ScrollView, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native'; +import { Platform, KeyboardAvoidingView, ActivityIndicator, Modal, ScrollView, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native'; import { styles } from './Login.styled'; import Ionicons from 'react-native-vector-icons/AntDesign'; import { useLogin } from './useLogin.hook'; @@ -63,22 +63,24 @@ export function Login() { )} - - - View Terms of Service - - actions.agree(!state.agree)}> - { state.agree && ( - - )} - { !state.agree && ( - - )} - I agree to Terms of Service - - + { Platform.OS !== 'ios' && ( + + + View Terms of Service + + actions.agree(!state.agree)}> + { state.agree && ( + + )} + { !state.agree && ( + + )} + I agree to Terms of Service + + + )} - { state.enabled && state.agree && ( + { state.enabled && (Platform.OS === 'ios' || state.agree) && ( { state.busy && ( @@ -88,7 +90,7 @@ export function Login() { )} )} - { (!state.enabled || !state.agree) && ( + { (!state.enabled || (Platform.OS !== 'ios' && !state.agree)) && ( Login diff --git a/app/mobile/src/access/reset/Reset.jsx b/app/mobile/src/access/reset/Reset.jsx index 14f01516..26d029a8 100644 --- a/app/mobile/src/access/reset/Reset.jsx +++ b/app/mobile/src/access/reset/Reset.jsx @@ -47,23 +47,25 @@ export function Reset() { autoCapitalize="none" placeholder="token" placeholderTextColor={Colors.grey} /> + + { Platform.OS !== 'ios' && ( + + + View Terms of Service + + actions.agree(!state.agree)}> + { state.agree && ( + + )} + { !state.agree && ( + + )} + I agree to Terms of Service + + + )} - - - View Terms of Service - - actions.agree(!state.agree)}> - { state.agree && ( - - )} - { !state.agree && ( - - )} - I agree to Terms of Service - - - - { state.enabled && state.agree && ( + { state.enabled && (Platform.OS === 'ios' || state.agree) && ( { state.busy && ( @@ -73,7 +75,7 @@ export function Reset() { )} )} - { (!state.enabled || !state.agree) && ( + { (!state.enabled || (Platform.OS !== 'ios' && !state.agree)) && ( Access From 2def0c1ee23a46d5c544c7a02a62bebb7fe806f3 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Mon, 3 Apr 2023 12:27:45 -0700 Subject: [PATCH 7/7] sanitizing urls --- app/mobile/package.json | 1 + .../src/session/conversation/topicItem/useTopicItem.hook.js | 4 ++-- app/mobile/yarn.lock | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/mobile/package.json b/app/mobile/package.json index 1c8b94c0..fae98b8b 100644 --- a/app/mobile/package.json +++ b/app/mobile/package.json @@ -10,6 +10,7 @@ "test": "jest" }, "dependencies": { + "@braintree/sanitize-url": "^6.0.2", "@react-native-clipboard/clipboard": "^1.11.1", "@react-native-firebase/app": "^17.2.0", "@react-native-firebase/messaging": "^17.2.0", diff --git a/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js b/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js index d3b5b4a1..e47e0b9b 100644 --- a/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js +++ b/app/mobile/src/session/conversation/topicItem/useTopicItem.hook.js @@ -9,7 +9,7 @@ import { useWindowDimensions, Text } from 'react-native'; import Colors from 'constants/Colors'; import { getCardByGuid } from 'context/cardUtil'; import { decryptTopicSubject } from 'context/sealUtil'; -import * as DOMPurify from 'dompurify'; +import { sanitizeUrl } from '@braintree/sanitize-url'; export function useTopicItem(item, hosting, remove, contentKey) { @@ -214,7 +214,7 @@ export function useTopicItem(item, hosting, remove, contentKey) { if (!!pattern.test(word)) { clickable.push({ group }); group = ''; - clickable.push( Linking.openURL(word)} style={{ fontStyle: 'italic' }}>{ word + ' ' }); + clickable.push( Linking.openURL(sanitizeUrl(word))} style={{ fontStyle: 'italic' }}>{ sanitizeUrl(word) + ' ' }); } else { group += `${word} `; diff --git a/app/mobile/yarn.lock b/app/mobile/yarn.lock index 0a93e42c..3741d0f2 100644 --- a/app/mobile/yarn.lock +++ b/app/mobile/yarn.lock @@ -1077,6 +1077,11 @@ resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@braintree/sanitize-url@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz#6110f918d273fe2af8ea1c4398a88774bb9fc12f" + integrity sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg== + "@egjs/hammerjs@^2.0.17": version "2.0.17" resolved "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz"