diff --git a/backend/src/Notifo.Domain.Integrations.Abstractions/IntegrationProperty.cs b/backend/src/Notifo.Domain.Integrations.Abstractions/IntegrationProperty.cs index 171d2f66..dfc70021 100644 --- a/backend/src/Notifo.Domain.Integrations.Abstractions/IntegrationProperty.cs +++ b/backend/src/Notifo.Domain.Integrations.Abstractions/IntegrationProperty.cs @@ -184,11 +184,11 @@ private bool TryGetString(string? input, [MaybeNullWhen(true)] out string error, } break; - case PropertyFormat.Url: + case PropertyFormat.HttpUrl: // We only allow http and https to enable the usage of URL field for HttpClient requests. if (!Uri.TryCreate(input, UriKind.Absolute, out var uri) || !((string[])["http", "https"]).Contains(uri.Scheme, StringComparer.OrdinalIgnoreCase)) { - error = Texts.IntegrationPropertyFormatUrl; + error = Texts.IntegrationPropertyFormatHttpUrl; return false; } diff --git a/backend/src/Notifo.Domain.Integrations.Abstractions/PropertyFormat.cs b/backend/src/Notifo.Domain.Integrations.Abstractions/PropertyFormat.cs index d624cff4..d66549c6 100644 --- a/backend/src/Notifo.Domain.Integrations.Abstractions/PropertyFormat.cs +++ b/backend/src/Notifo.Domain.Integrations.Abstractions/PropertyFormat.cs @@ -11,5 +11,5 @@ public enum PropertyFormat { None, Email, - Url + HttpUrl } diff --git a/backend/src/Notifo.Domain.Integrations.Abstractions/Resources/Texts.Designer.cs b/backend/src/Notifo.Domain.Integrations.Abstractions/Resources/Texts.Designer.cs index e1907cdc..a9c1d200 100644 --- a/backend/src/Notifo.Domain.Integrations.Abstractions/Resources/Texts.Designer.cs +++ b/backend/src/Notifo.Domain.Integrations.Abstractions/Resources/Texts.Designer.cs @@ -79,11 +79,11 @@ internal static string IntegrationPropertyFormatEmail { } /// - /// Looks up a localized string similar to Field is not a valid URL (remember about the protocol).. + /// Looks up a localized string similar to Field is not a valid URL (remember about the protocol - http or https).. /// - internal static string IntegrationPropertyFormatUrl { + internal static string IntegrationPropertyFormatHttpUrl { get { - return ResourceManager.GetString("IntegrationPropertyFormatUrl", resourceCulture); + return ResourceManager.GetString("IntegrationPropertyFormatHttpUrl", resourceCulture); } } diff --git a/backend/src/Notifo.Domain.Integrations.Abstractions/Resources/Texts.resx b/backend/src/Notifo.Domain.Integrations.Abstractions/Resources/Texts.resx index f98786c1..3e20ce90 100644 --- a/backend/src/Notifo.Domain.Integrations.Abstractions/Resources/Texts.resx +++ b/backend/src/Notifo.Domain.Integrations.Abstractions/Resources/Texts.resx @@ -123,8 +123,8 @@ Field is not a valid e-mail. - - Field is not a valid URL (remember about the protocol). + + Field is not a valid URL (remember about the protocol - http or https). Not a valid boolean value. diff --git a/backend/src/Notifo.Domain.Integrations/Http/HttpIntegration.cs b/backend/src/Notifo.Domain.Integrations/Http/HttpIntegration.cs index 4608787e..dea8ce2b 100644 --- a/backend/src/Notifo.Domain.Integrations/Http/HttpIntegration.cs +++ b/backend/src/Notifo.Domain.Integrations/Http/HttpIntegration.cs @@ -19,7 +19,7 @@ public sealed partial class HttpIntegration : IIntegration EditorDescription = Texts.Webhook_URLHints, IsRequired = true, Summary = true, - Format = PropertyFormat.Url, + Format = PropertyFormat.HttpUrl, }; private static readonly IntegrationProperty HttpMethodProperty = new IntegrationProperty("Method", PropertyType.Text) diff --git a/backend/tests/Notifo.Domain.Tests/Integrations/IntegrationPropertyTests.cs b/backend/tests/Notifo.Domain.Tests/Integrations/IntegrationPropertyTests.cs index 8621231f..2e41cdc5 100644 --- a/backend/tests/Notifo.Domain.Tests/Integrations/IntegrationPropertyTests.cs +++ b/backend/tests/Notifo.Domain.Tests/Integrations/IntegrationPropertyTests.cs @@ -171,7 +171,7 @@ public void Should_fail_if_url_is_invalid(string? input) var property = new IntegrationProperty("key", PropertyType.Text) { - Format = PropertyFormat.Url + Format = PropertyFormat.HttpUrl }; Assert.Throws(() => property.GetString(source)); @@ -191,7 +191,7 @@ public void Should_get_url_if_value_is_valid(string? input) var property = new IntegrationProperty("key", PropertyType.Text) { - Format = PropertyFormat.Url + Format = PropertyFormat.HttpUrl }; Assert.Equal(input, property.GetString(source)); diff --git a/frontend/src/app/pages/app/AppAuth.tsx b/frontend/src/app/pages/app/AppAuth.tsx index aad4b058..e6032748 100644 --- a/frontend/src/app/pages/app/AppAuth.tsx +++ b/frontend/src/app/pages/app/AppAuth.tsx @@ -86,7 +86,7 @@ const FormSchema = Yup.object().shape({ // Valid URL. signoutRedirectUrl: Yup.string() - .label(texts.auth.signoutRedirectUrl).urlI18n(), + .label(texts.auth.signoutRedirectUrl).httpUrlI18n(), }); const AuthForm = ({ appDetails, scheme }: { scheme?: AuthSchemeDto } & AppAuthProps) => { diff --git a/frontend/src/app/pages/app/AppSettings.tsx b/frontend/src/app/pages/app/AppSettings.tsx index fd59e7bc..a0585399 100644 --- a/frontend/src/app/pages/app/AppSettings.tsx +++ b/frontend/src/app/pages/app/AppSettings.tsx @@ -28,7 +28,7 @@ const FormSchema = Yup.object().shape({ // Valid URL confirmUrl: Yup.string().nullable() - .label(texts.app.confirmUrl).urlI18n(), + .label(texts.app.confirmUrl).httpUrlI18n(), }); export interface AppSettingsProps { diff --git a/frontend/src/app/pages/integrations/IntegrationDialog.tsx b/frontend/src/app/pages/integrations/IntegrationDialog.tsx index 9b8cf5b9..48786cab 100644 --- a/frontend/src/app/pages/integrations/IntegrationDialog.tsx +++ b/frontend/src/app/pages/integrations/IntegrationDialog.tsx @@ -129,8 +129,8 @@ export const IntegrationDialog = (props: IntegrationDialogProps) => { case "Email": propertyType = propertyType.emailI18n(); break; - case "Url": - propertyType = propertyType.urlI18n(); + case "HttpUrl": + propertyType = propertyType.httpUrlI18n(); break; } } @@ -289,7 +289,7 @@ export const FormField = ({ property }: { property: IntegrationPropertyDto }) => ); - case 'Url': + case 'HttpUrl': return ( diff --git a/frontend/src/app/service/service.ts b/frontend/src/app/service/service.ts index 06640540..3c2530cd 100644 --- a/frontend/src/app/service/service.ts +++ b/frontend/src/app/service/service.ts @@ -7437,7 +7437,7 @@ export interface IntegrationPropertyDto { } export type PropertyType = "Text" | "Number" | "MultilineText" | "Password" | "Boolean"; -export type PropertyFormat = "None" | "Email" | "Url"; +export type PropertyFormat = "None" | "Email" | "HttpUrl"; export interface IntegrationCreatedDto { /** The ID of the integration. */ diff --git a/frontend/src/app/shared/utils/model.ts b/frontend/src/app/shared/utils/model.ts index 723cfba2..f4c4ef59 100644 --- a/frontend/src/app/shared/utils/model.ts +++ b/frontend/src/app/shared/utils/model.ts @@ -5,7 +5,7 @@ * Copyright (c) Sebastian Stehle. All rights reserved. */ -import { ChannelCondition, ChannelRequired, ChannelSend, ConfirmMode, IsoDayOfWeek, PropertyFormat, SchedulingType, TopicChannel } from '@app/service'; +import { ChannelCondition, ChannelRequired, ChannelSend, ConfirmMode, IsoDayOfWeek , SchedulingType, TopicChannel } from '@app/service'; import { texts } from '@app/texts'; export const CHANNELS = [ diff --git a/frontend/src/app/shared/utils/yup.ts b/frontend/src/app/shared/utils/yup.ts index 4909b324..dfbc2c29 100644 --- a/frontend/src/app/shared/utils/yup.ts +++ b/frontend/src/app/shared/utils/yup.ts @@ -13,11 +13,11 @@ function emailI18n(this: Yup.StringSchema) { return this.email(texts.validation.emailFn); } -function urlI18n(this: Yup.StringSchema) { +function httpUrlI18n(this: Yup.StringSchema) { // This regular expression is built on top of the one // from Yup, but it also allows localhost. // See: https://github.com/jquense/yup/issues/224 - return this.matches(/^(?:(?:https?):\/\/|www\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*\)|[A-Z0-9+&@#\/%=~_|$[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])$/i , texts.validation.urlFn); + return this.matches(/^(?:(?:https?):\/\/|www\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*\)|[A-Z0-9+&@#\/%=~_|$[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])$/i , texts.validation.httpUrlFn); } function requiredI18nNumber(this: Yup.NumberSchema) { @@ -64,7 +64,7 @@ export function extendYup() { Yup.addMethod(Yup.object, 'atLeastOneStringI18n', atLeastOneStringI18n); Yup.addMethod(Yup.string, 'emailI18n', emailI18n); - Yup.addMethod(Yup.string, 'urlI18n', urlI18n); + Yup.addMethod(Yup.string, 'httpUrlI18n', httpUrlI18n); Yup.addMethod(Yup.string, 'requiredI18n', requiredI18n); Yup.addMethod(Yup.string, 'topicI18n', topicI18n); diff --git a/frontend/src/app/texts/en.ts b/frontend/src/app/texts/en.ts index 283693f2..641ab342 100644 --- a/frontend/src/app/texts/en.ts +++ b/frontend/src/app/texts/en.ts @@ -433,6 +433,7 @@ export const EN = { validation: { atLeastOnString: (p: { label?: string }) => `${p.label} needs at least one value.`, emailFn: (p: { label?: string }) => `${p.label} must be a valid email address.`, + httpUrlFn: (p: { label?: string }) => `${p.label} must be a valid HTTP URL (include the protocol - http or https).`, lessThanFn: (p: { label?: string; less: number }) => `${p.label} must be less than ${p.less || 0}.`, maxFn: (p: { label?: string; max: number }) => `${p.label} must not greater than ${p.max}.`, maxItemsFn: (p: { label?: string; max: number }) => `${p.label} must not have more than ${p.max}.`, @@ -444,6 +445,5 @@ export const EN = { patternFn: (p: { label?: string }) => `${p.label} is not in a valid format.`, requiredFn: (p: { label?: string }) => `${p.label} is required.`, topicFn: (p: { label?: string }) => `${p.label} must be a valid topic.`, - urlFn: (p: { label?: string }) => `${p.label} must be a valid URL with a protocol (e.g. https).`, }, }; diff --git a/frontend/src/app/texts/tr.ts b/frontend/src/app/texts/tr.ts index 70158e04..f2a3ff3e 100644 --- a/frontend/src/app/texts/tr.ts +++ b/frontend/src/app/texts/tr.ts @@ -417,6 +417,7 @@ export const TR = { validation: { atLeastOnString: (p: { label?: string }) => `${p.label} en az bir değere sahip olmalıdır.`, emailFn: (p: { label?: string }) => `${p.label} geçerli bir e-posta adresi olmalıdır.`, + httpUrlFn: (p: { label?: string }) => `${p.label} geçerli bir HTTP URL'si olmalı (protokolü ekleyin - http veya https).`, lessThanFn: (p: { label?: string; less: number }) => `${p.label} ${p.less || 0}\`dan küçük olmalıdır.`, maxFn: (p: { label?: string; max: number }) => `${p.label} ${p.max}\`dan büyük olmamalıdır.`, maxItemsFn: (p: { label?: string; max: number }) => `${p.label} en fazla ${p.max} öğeye sahip olmalıdır.`, @@ -428,6 +429,5 @@ export const TR = { patternFn: (p: { label?: string }) => `${p.label} geçerli bir formatta değil.`, requiredFn: (p: { label?: string }) => `${p.label} zorunludur.`, topicFn: (p: { label?: string }) => `${p.label} geçerli bir konu olmalıdır.`, - urlFn: (p: { label?: string }) => `${p.label} geçerli bir URL olmalıdır.`, }, }; diff --git a/frontend/src/app/typings/yup.d.ts b/frontend/src/app/typings/yup.d.ts index 406ea434..2e831209 100644 --- a/frontend/src/app/typings/yup.d.ts +++ b/frontend/src/app/typings/yup.d.ts @@ -13,7 +13,7 @@ declare module 'yup' { interface StringSchema { emailI18n(): StringSchema; - urlI18n(): StringSchema; + httpUrlI18n(): StringSchema; requiredI18n(): StringSchema; diff --git a/tools/sdk/Notifo.SDK/Generated.cs b/tools/sdk/Notifo.SDK/Generated.cs index 51b4d926..1c72de99 100644 --- a/tools/sdk/Notifo.SDK/Generated.cs +++ b/tools/sdk/Notifo.SDK/Generated.cs @@ -17903,8 +17903,8 @@ public enum PropertyFormat [System.Runtime.Serialization.EnumMember(Value = @"Email")] Email = 1, - [System.Runtime.Serialization.EnumMember(Value = @"Url")] - Url = 2, + [System.Runtime.Serialization.EnumMember(Value = @"HttpUrl")] + HttpUrl = 2, }