Skip to content
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
18 changes: 18 additions & 0 deletions apps/mobile/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ const createConfig = (): Omit<ExpoConfig, 'extra'> & { extra: { eas: EASConfig }
config: {
usesNonExemptEncryption: false,
},
infoPlist: {
// Allow connecting to self-hosted Open WebUI servers that are reachable
// only over plain HTTP (local network, Docker, Raspberry Pi, Tailscale).
NSAppTransportSecurity: {
NSAllowsArbitraryLoads: true,
NSAllowsLocalNetworking: true,
},
},
},
android: {
package: appId,
Expand Down Expand Up @@ -107,6 +115,16 @@ const createConfig = (): Omit<ExpoConfig, 'extra'> & { extra: { eas: EASConfig }
enableBackgroundRecording: false,
},
],
[
'expo-build-properties',
{
android: {
// Allow plain HTTP connections to self-hosted servers (local network,
// Tailscale, etc.). Mirrors iOS NSAllowsArbitraryLoads above.
usesCleartextTraffic: true,
},
},
],
]),
newArchEnabled: true,
extra,
Expand Down
2 changes: 1 addition & 1 deletion i18n/mobile/shared/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"TEXT_INVALID_EMAIL": "Please enter a valid email address",
"TEXT_REQUIRED_EMAIL": "Please enter your email",
"TEXT_REQUIRED_PASSWORD": "Please enter your password",
"TEXT_INVALID_URL": "Please enter a valid URL in format https://your.domain",
"TEXT_INVALID_URL": "Please enter a valid server URL, e.g. https://your.domain or http://192.168.1.10:3000",
"TEXT_REQUIRED_FOLDER_NAME": "Please enter a folder name"
},
"COMMON": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { i18n } from '@ronas-it/react-native-common-modules/i18n';
import * as Yup from 'yup';
import { emailValidator } from '@open-webui-react-native/mobile/shared/utils/validation';
import { emailValidator, serverUrlValidator } from '@open-webui-react-native/mobile/shared/utils/validation';

export class EmailFormSchema {
public email: string;
Expand All @@ -17,21 +17,7 @@ export class EmailFormSchema {
return Yup.object().shape({
email: emailValidator().required(i18n.t('SHARED.VALIDATION.TEXT_REQUIRED_EMAIL')),
password: Yup.string().required(i18n.t('SHARED.VALIDATION.TEXT_REQUIRED_PASSWORD')),
url: Yup.string()
.url(i18n.t('SHARED.VALIDATION.TEXT_INVALID_URL'))
.test('no-path', i18n.t('SHARED.VALIDATION.TEXT_INVALID_URL'), (value) => {
if (!value) return true;

try {
const normalizedValue = value.trim();
const url = new URL(normalizedValue);
const normalizedPath = url.pathname.replace(/\/+$/, '/');

return normalizedPath === '/' && !url.search && !url.hash;
} catch {
return false;
}
}),
url: serverUrlValidator(),
});
}
}
1 change: 1 addition & 0 deletions libs/mobile/shared/utils/validation/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './email-validation';
export * from './server-url-validation';
29 changes: 29 additions & 0 deletions libs/mobile/shared/utils/validation/src/server-url-validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { i18n } from '@ronas-it/react-native-common-modules/i18n';
import * as Yup from 'yup';

export const serverUrlValidator = (): Yup.StringSchema =>
Yup.string()
.trim()
.test('server-url', i18n.t('SHARED.VALIDATION.TEXT_INVALID_URL'), (value) => {
if (!value) {
return true;
}

try {
const url = new URL(value.trim());

if (url.protocol !== 'http:' && url.protocol !== 'https:') {
return false;
}

if (!url.hostname) {
return false;
}

const normalizedPath = url.pathname.replace(/\/+$/, '/');

return normalizedPath === '/' && !url.search && !url.hash;
} catch {
return false;
}
});
Loading