diff --git a/sanityv3/schemas/editors/blockContentType.tsx b/sanityv3/schemas/editors/blockContentType.tsx index 14d944d4f..59ac24dc6 100644 --- a/sanityv3/schemas/editors/blockContentType.tsx +++ b/sanityv3/schemas/editors/blockContentType.tsx @@ -6,6 +6,7 @@ import { Flags } from '../../src/lib/datasetHelpers' import { ExternalLinkRenderer, SubScriptRenderer, SuperScriptRenderer } from '../components' import routes from '../routes' import { defaultColors } from '../defaultColors' +import { strictExternal, warnHttpExternal, warnHttpOrNotValidSlugExternal } from '../validations/validateSlug' export type BlockContentProps = { h2?: boolean @@ -181,7 +182,12 @@ export const configureBlockContent = (options: BlockContentProps = {}): BlockDef { name: 'href', type: 'url', - validation: (Rule: any) => Rule.uri({ scheme: ['http', 'https', 'tel', 'mailto'] }), + validation: (Rule: any) => + Rule.uri({ scheme: ['http', 'https', 'tel', 'mailto'] }) + .custom((value: any, context: ValidationContext) => { + return warnHttpOrNotValidSlugExternal(value, context) + }) + .error(), }, ], } diff --git a/sanityv3/schemas/objects/linkSelector.tsx b/sanityv3/schemas/objects/linkSelector.tsx index 2300559da..908729d99 100644 --- a/sanityv3/schemas/objects/linkSelector.tsx +++ b/sanityv3/schemas/objects/linkSelector.tsx @@ -9,6 +9,7 @@ import { AnchorLinkDescription } from './anchorReferenceField' // eslint-disable-next-line import/no-unresolved import { defaultLanguage } from '../../languages' import { apiVersion } from '../../sanity.client' +import { warnHttpOrNotValidSlugExternal } from '../validations/validateSlug' export type ReferenceTarget = { type: string @@ -118,7 +119,13 @@ export const getLinkSelectorFields = (labelFieldset?: string, flag?: string) => const { parent } = context as { parent: LinkSelector } if (isHidden(parent)) return true const connectedField = parent?.linkToOtherLanguage ? parent?.referenceToOtherLanguage : parent?.reference - return validateInternalOrExternalUrl(value, connectedField) + const internalValidation = validateInternalOrExternalUrl(value, connectedField) + //If message from internalValidation return that if not continue to check external url + if (internalValidation) { + return warnHttpOrNotValidSlugExternal(value, context) + } else { + return internalValidation + } }), hidden: ({ parent }: { parent: LinkSelector }) => isHidden(parent), }, diff --git a/sanityv3/schemas/validations/checkEquinorUrls.ts b/sanityv3/schemas/validations/checkEquinorUrls.ts new file mode 100644 index 000000000..5f39c3250 --- /dev/null +++ b/sanityv3/schemas/validations/checkEquinorUrls.ts @@ -0,0 +1,5 @@ +import { getAllDomainUrls } from '../../../satellitesConfig' + +export const isEquinorUrl = (slug: string) => { + return getAllDomainUrls().some((allowedUrl) => slug.toLowerCase().startsWith(allowedUrl)) +} diff --git a/sanityv3/schemas/validations/validateSlug.ts b/sanityv3/schemas/validations/validateSlug.ts index 01ab31878..aa355fbbd 100644 --- a/sanityv3/schemas/validations/validateSlug.ts +++ b/sanityv3/schemas/validations/validateSlug.ts @@ -1,6 +1,7 @@ import { ValidationContext } from 'sanity' import { apiVersion } from '../../sanity.client' import { Flags } from '../../src/lib/datasetHelpers' +import { isEquinorUrl } from './checkEquinorUrls' const validateIsUniqueWithinLocale = async (slug: string, context: ValidationContext) => { const { document, getClient } = context @@ -41,3 +42,28 @@ export const withSlugValidation = (options: any) => { } : options } + +const stringIsSlug = + /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/ +const httpRegex = /^http:\/\/[^\s]+$/ +export const warnHttpOrNotValidSlugExternal = (slug: string) => { + if (!slug) return true + if (!slug.startsWith('http')) return true // ignore mailto , tel + const isHttp = httpRegex.test(slug) + const validSlug = stringIsSlug.test(slug) + const slugWithOutQueryParam = slug.split('?')[0] + const isInvalidEquinorUrl = slugWithOutQueryParam !== slugWithOutQueryParam.toLowerCase() && isEquinorUrl(slug) + + let message = '' + if (isHttp) { + message = 'Use https in url. ' + } + if (!validSlug) { + message = message.concat(`Not a valid url.`) + } + + if (isInvalidEquinorUrl) { + message = message.concat('Equinor urls should contain lowercase letters only.') + } + return isHttp || !validSlug || isInvalidEquinorUrl ? message : true +} diff --git a/satellitesConfig.js b/satellitesConfig.js index b6dc08600..32f4b9738 100644 --- a/satellitesConfig.js +++ b/satellitesConfig.js @@ -185,3 +185,7 @@ export const getDomain = (dataset) => websiteDomains[dataset]?.url || 'Domain no export const getMetaTitleSuffix = (dataset) => { return websiteDomains[dataset]?.meta || 'Equinor' } + +export const getAllDomainUrls = () => { + return Object.keys(datasets).map((dataset) => websiteDomains[dataset]?.url) +}