diff --git a/seaside/src/administration/component/usereditor/UserEditor.vue b/seaside/src/administration/component/usereditor/UserEditor.vue index 4a1fd125..bc5c7b8d 100644 --- a/seaside/src/administration/component/usereditor/UserEditor.vue +++ b/seaside/src/administration/component/usereditor/UserEditor.vue @@ -1,184 +1,183 @@ \ No newline at end of file diff --git a/seaside/src/common/services/RegexPattern.ts b/seaside/src/common/services/RegexPattern.ts new file mode 100644 index 00000000..856392d3 --- /dev/null +++ b/seaside/src/common/services/RegexPattern.ts @@ -0,0 +1,3 @@ +export const URL_PATTERN = /^(((https?):\/\/)(%[0-9A-Fa-f]{2}|[-()_.!~*';/?:@&=+$,A-Za-z0-9])+)([).!';/?:,][[:blank:]])?$/; +export const MAIL_PATTERN = /^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,7}$/; +export const ULID_PATTERN = /^[A-Z]*(:[A-Z]{2}[0-7][0-9A-HJKMNP-TV-Z]{25})?$/; diff --git a/seaside/src/configuration/components/feedslist/FeedEditor.vue b/seaside/src/configuration/components/feedslist/FeedEditor.vue index 727061cd..8de2c226 100644 --- a/seaside/src/configuration/components/feedslist/FeedEditor.vue +++ b/seaside/src/configuration/components/feedslist/FeedEditor.vue @@ -39,7 +39,8 @@ import { Observable, Subject } from 'rxjs'; import ModalWindow from '@/common/components/ModalWindow.vue'; import TagInput from '@/common/components/TagInput.vue'; import tagsService from '@/techwatch/services/TagsService'; -import feedService, { URL_PATTERN } from '@/configuration/services/FeedService'; +import feedService from '@/configuration/services/FeedService'; +import { URL_PATTERN } from '@/common/services/RegexPattern'; @Component({ name: 'FeedEditor', diff --git a/seaside/src/configuration/services/FeedService.ts b/seaside/src/configuration/services/FeedService.ts index 0c6b81d9..d146a024 100644 --- a/seaside/src/configuration/services/FeedService.ts +++ b/seaside/src/configuration/services/FeedService.ts @@ -1,20 +1,14 @@ -import {map, switchMap, take} from "rxjs/operators"; -import {HttpStatusError} from "@/common/errors/HttpStatusError"; -import {Feed} from "@/configuration/model/Feed.type"; -import {Page} from "@/services/model/Page"; -import {from, Observable, of, throwError} from "rxjs"; +import { map, switchMap, take } from 'rxjs/operators'; +import { HttpStatusError } from '@/common/errors/HttpStatusError'; +import { Feed } from '@/configuration/model/Feed.type'; +import { Page } from '@/services/model/Page'; +import { from, Observable, of, throwError } from 'rxjs'; import rest from '@/common/services/RestWrapper'; -import {OpPatch} from "json-patch"; -import {AtomFeed, ScrapFeedHeaderResponse} from "@/configuration/model/GraphQLScraper.type"; -import {SearchFeedsRequest, SearchFeedsResponse} from "@/configuration/model/SearchFeedsResponse.type"; -import {send} from "@/common/services/GraphQLClient"; - -export const URL_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 +import { OpPatch } from 'json-patch'; +import { AtomFeed, ScrapFeedHeaderResponse } from '@/configuration/model/GraphQLScraper.type'; +import { SearchFeedsRequest, SearchFeedsResponse } from '@/configuration/model/SearchFeedsResponse.type'; +import { send } from '@/common/services/GraphQLClient'; +import { URL_PATTERN } from '@/common/services/RegexPattern'; export class FeedService { @@ -26,7 +20,7 @@ export class FeedService { totalCount entities {_id name location tags} } - }` + }`; private static readonly SCRAP_FEED_HEAD_REQUEST = `#graphql query ScrapFeedHeader($link: URI!) { @@ -56,7 +50,7 @@ export class FeedService { totalPage: Math.ceil( res.data.feedsSearch.totalCount / (options._pp | FeedService.DEFAULT_PER_PAGE)), data: of(res.data.feedsSearch.entities), - } + }; }), take(1), ); @@ -65,7 +59,7 @@ export class FeedService { public add(feed: Feed): Observable { return rest.post('/feeds', feed).pipe( switchMap(this.responseToFeed), - take(1) + take(1), ); } @@ -74,15 +68,15 @@ export class FeedService { return rest.put(`/feeds/${feed._id}`, feed).pipe( switchMap(this.responseToFeed), map((updatedFeed: Feed) => updatedFeed._id), - take(1) + take(1), ); } else { const jsonPatch: OpPatch[] = []; - jsonPatch.push({op: 'remove', path: `/feeds/${feed._id}`}); - jsonPatch.push({op: 'add', path: '/feeds', value: feed}); + jsonPatch.push({ op: 'remove', path: `/feeds/${feed._id}` }); + jsonPatch.push({ op: 'add', path: '/feeds', value: feed }); return this.patch(jsonPatch).pipe( - map(updated => updated.pop()) + map(updated => updated.pop()), ); } } @@ -90,22 +84,22 @@ export class FeedService { public remove(id: string): Observable { return rest.delete(`/feeds/${id}`).pipe( switchMap(this.responseToFeed), - take(1) + take(1), ); } public bulkRemove(ids: string[]): Observable { const jsonPatch: OpPatch[] = []; - ids.forEach(id => jsonPatch.push({op: 'remove', path: `/feeds/${id}`})); + ids.forEach(id => jsonPatch.push({ op: 'remove', path: `/feeds/${id}` })); return this.patch(jsonPatch).pipe( - map(deleted => deleted.length) + map(deleted => deleted.length), ); } private patch(payload: OpPatch[]): Observable { return rest.patch('/feeds', payload).pipe( switchMap(this.responseToFeed), - take(1) + take(1), ); } @@ -125,7 +119,7 @@ export class FeedService { return throwError(() => new Error('Argument link must be a valid URL !')); } - return send(FeedService.SCRAP_FEED_HEAD_REQUEST, {link: link}).pipe( + return send(FeedService.SCRAP_FEED_HEAD_REQUEST, { link: link }).pipe( map(data => data.data.scrapFeedHeader), map((atom: AtomFeed) => ({ name: atom.title, @@ -140,7 +134,7 @@ export class FeedService { return throwError(() => new Error('Feed id is mandatory !')); } - return send<{ subscribe: Feed }>(FeedService.FEED_SUBSCRIBE, {feedId: id}).pipe( + return send<{ subscribe: Feed }>(FeedService.FEED_SUBSCRIBE, { feedId: id }).pipe( map(data => data.data.subscribe), take(1), ); diff --git a/seaside/src/layout/services/ScraperService.ts b/seaside/src/layout/services/ScraperService.ts index 1033307b..bf45f483 100644 --- a/seaside/src/layout/services/ScraperService.ts +++ b/seaside/src/layout/services/ScraperService.ts @@ -1,13 +1,7 @@ -import {Observable, throwError} from "rxjs"; -import {map, take} from "rxjs/operators"; -import {send} from "@/common/services/GraphQLClient"; - -const URL_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 +import { Observable, throwError } from 'rxjs'; +import { map, take } from 'rxjs/operators'; +import { send } from '@/common/services/GraphQLClient'; +import { URL_PATTERN } from '@/common/services/RegexPattern'; export class ScraperService { private static readonly SCRAP_SINGLE_NEWS_REQUEST = `#graphql @@ -22,9 +16,9 @@ export class ScraperService { return throwError(() => new Error('Argument link must be a valid URL !')); } - return send(ScraperService.SCRAP_SINGLE_NEWS_REQUEST, {newsLink: link}).pipe( + return send(ScraperService.SCRAP_SINGLE_NEWS_REQUEST, { newsLink: link }).pipe( take(1), - map(() => undefined) + map(() => undefined), ); } }