1
0
mirror of https://github.com/uetchy/namae.git synced 2025-07-02 06:20:02 +09:00

fix: properly validate URL

This commit is contained in:
uetchy 2020-06-11 22:00:16 +09:00
parent b8ce81b276
commit 4232d0435d
11 changed files with 45 additions and 19 deletions

View File

@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"node-fetch": "^2.6.0", "node-fetch": "^2.6.0",
"npm-name": "^6.0.0", "npm-name": "^6.0.0",
"validator": "^13.1.0",
"whois-json": "^2.0.4" "whois-json": "^2.0.4"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,3 +1,4 @@
import isURL from 'validator/lib/isURL';
import {send, sendError, fetch, NowRequest, NowResponse} from '../util/http'; import {send, sendError, fetch, NowRequest, NowResponse} from '../util/http';
export default async function handler( export default async function handler(
@ -10,12 +11,8 @@ export default async function handler(
return sendError(res, new Error('no query given')); return sendError(res, new Error('no query given'));
} }
if ( if (!isURL(query)) {
!/^[(http(s)?)://(www.)?a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)$/.test( return sendError(res, new Error('Invalid URL: ' + query));
query,
)
) {
return sendError(res, new Error('Invalid characters'));
} }
try { try {

View File

@ -21,7 +21,7 @@ import JsOrgCard from './providers/JsOrg';
import GithubSearchCard from './providers/GitHubSearch'; import GithubSearchCard from './providers/GitHubSearch';
import AppStoreCard from './providers/AppStore'; import AppStoreCard from './providers/AppStore';
import HerokuCard from './providers/Heroku'; import HerokuCard from './providers/Heroku';
import NowCard from './providers/Now'; import VercelCard from './providers/Vercel';
import NtaCard from './providers/Nta'; import NtaCard from './providers/Nta';
import NetlifyCard from './providers/Netlify'; import NetlifyCard from './providers/Netlify';
import OcamlCard from './providers/Ocaml'; import OcamlCard from './providers/Ocaml';
@ -45,7 +45,7 @@ const Index: React.FC<{query: string}> = ({query}) => {
<RubyGemsCard query={query} /> <RubyGemsCard query={query} />
<LinuxCard query={query} /> <LinuxCard query={query} />
<OcamlCard query={query} /> <OcamlCard query={query} />
<NowCard query={query} /> <VercelCard query={query} />
<HerokuCard query={query} /> <HerokuCard query={query} />
<NetlifyCard query={query} /> <NetlifyCard query={query} />
<JsOrgCard query={query} /> <JsOrgCard query={query} />

View File

@ -7,7 +7,11 @@ import {zones} from '../../../util/zones';
const DomainCard: React.FC<{query: string}> = ({query}) => { const DomainCard: React.FC<{query: string}> = ({query}) => {
const {t} = useTranslation(); const {t} = useTranslation();
const lowerCase = query.toLowerCase();
const sanitizedQuery = query
.replace(/[^0-9a-zA-Z_-]/g, '')
.replace(/_/g, '-');
const lowerCase = sanitizedQuery.toLowerCase();
const domainHackSuggestions = zones const domainHackSuggestions = zones
.map((zone) => new RegExp(`${zone}$`).exec(lowerCase.slice(1))) .map((zone) => new RegExp(`${zone}$`).exec(lowerCase.slice(1)))

View File

@ -6,7 +6,11 @@ import {Card, Repeater, DedicatedAvailability} from '../core';
const HerokuCard: React.FC<{query: string}> = ({query}) => { const HerokuCard: React.FC<{query: string}> = ({query}) => {
const {t} = useTranslation(); const {t} = useTranslation();
const lowerCase = query.toLowerCase();
const sanitizedQuery = query
.replace(/[^0-9a-zA-Z_-]/g, '')
.replace(/_/g, '-');
const lowerCase = sanitizedQuery.toLowerCase();
const names = [lowerCase]; const names = [lowerCase];

View File

@ -6,7 +6,11 @@ import {Card, Repeater, DedicatedAvailability} from '../core';
const JsOrgCard: React.FC<{query: string}> = ({query}) => { const JsOrgCard: React.FC<{query: string}> = ({query}) => {
const {t} = useTranslation(); const {t} = useTranslation();
const lowerCase = query.toLowerCase();
const sanitizedQuery = query
.replace(/[^0-9a-zA-Z_-]/g, '')
.replace(/_/g, '-');
const lowerCase = sanitizedQuery.toLowerCase();
const names = [lowerCase]; const names = [lowerCase];

View File

@ -6,7 +6,11 @@ import {Card, Repeater, DedicatedAvailability} from '../core';
const NetlifyCard: React.FC<{query: string}> = ({query}) => { const NetlifyCard: React.FC<{query: string}> = ({query}) => {
const {t} = useTranslation(); const {t} = useTranslation();
const lowerCase = query.toLowerCase();
const sanitizedQuery = query
.replace(/[^0-9a-zA-Z_-]/g, '')
.replace(/_/g, '-');
const lowerCase = sanitizedQuery.toLowerCase();
const names = [lowerCase]; const names = [lowerCase];

View File

@ -19,8 +19,8 @@ const NpmCard: React.FC<{query: string}> = ({query}) => {
<DedicatedAvailability <DedicatedAvailability
name={name} name={name}
service="npm" service="npm"
message="Read publishing guide" message={`See ${name}`}
link="https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry" link={`https://www.npmjs.com/package/${name}`}
messageIfTaken={`See ${name}`} messageIfTaken={`See ${name}`}
linkIfTaken={`https://www.npmjs.com/package/${name}`} linkIfTaken={`https://www.npmjs.com/package/${name}`}
icon={<FaNpm />} icon={<FaNpm />}

View File

@ -6,7 +6,11 @@ import {Card, DedicatedAvailability, Repeater} from '../core';
const S3Card: React.FC<{query: string}> = ({query}) => { const S3Card: React.FC<{query: string}> = ({query}) => {
const {t} = useTranslation(); const {t} = useTranslation();
const lowerCase = query.toLowerCase();
const sanitizedQuery = query
.replace(/[^0-9a-zA-Z_-]/g, '')
.replace(/_/g, '-');
const lowerCase = sanitizedQuery.toLowerCase();
const names = [lowerCase]; const names = [lowerCase];

View File

@ -6,7 +6,11 @@ import {Card, DedicatedAvailability, Repeater} from '../core';
const SlackCard: React.FC<{query: string}> = ({query}) => { const SlackCard: React.FC<{query: string}> = ({query}) => {
const {t} = useTranslation(); const {t} = useTranslation();
const lowerCase = query.toLowerCase();
const sanitizedQuery = query
.replace(/[^0-9a-zA-Z_-]/g, '')
.replace(/_/g, '-');
const lowerCase = sanitizedQuery.toLowerCase();
const names = [lowerCase]; const names = [lowerCase];

View File

@ -4,9 +4,13 @@ import {NowIcon} from '../../Icons';
import {Card, Repeater, DedicatedAvailability} from '../core'; import {Card, Repeater, DedicatedAvailability} from '../core';
const NowCard: React.FC<{query: string}> = ({query}) => { const VercelCard: React.FC<{query: string}> = ({query}) => {
const {t} = useTranslation(); const {t} = useTranslation();
const lowerCase = query.toLowerCase();
const sanitizedQuery = query
.replace(/[^0-9a-zA-Z_-]/g, '')
.replace(/_/g, '-');
const lowerCase = sanitizedQuery.toLowerCase();
const names = [lowerCase]; const names = [lowerCase];
@ -27,4 +31,4 @@ const NowCard: React.FC<{query: string}> = ({query}) => {
); );
}; };
export default NowCard; export default VercelCard;