]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/shared/shared-moderation/abuse.service.ts
Update build steps for localization
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-moderation / abuse.service.ts
1 import { omit } from 'lodash-es'
2 import { SortMeta } from 'primeng/api'
3 import { Observable } from 'rxjs'
4 import { catchError, map } from 'rxjs/operators'
5 import { HttpClient, HttpParams } from '@angular/common/http'
6 import { Injectable } from '@angular/core'
7 import { RestExtractor, RestPagination, RestService } from '@app/core'
8 import { I18n } from '@ngx-translate/i18n-polyfill'
9 import {
10 AbuseCreate,
11 AbuseFilter,
12 AbuseMessage,
13 AbusePredefinedReasonsString,
14 AbuseState,
15 AbuseUpdate,
16 AdminAbuse,
17 ResultList,
18 UserAbuse
19 } from '@shared/models'
20 import { environment } from '../../../environments/environment'
21
22 @Injectable()
23 export class AbuseService {
24 private static BASE_ABUSE_URL = environment.apiUrl + '/api/v1/abuses'
25 private static BASE_MY_ABUSE_URL = environment.apiUrl + '/api/v1/users/me/abuses'
26
27 constructor (
28 private i18n: I18n,
29 private authHttp: HttpClient,
30 private restService: RestService,
31 private restExtractor: RestExtractor
32 ) { }
33
34 getAdminAbuses (options: {
35 pagination: RestPagination,
36 sort: SortMeta,
37 search?: string
38 }): Observable<ResultList<AdminAbuse>> {
39 const { pagination, sort, search } = options
40 const url = AbuseService.BASE_ABUSE_URL
41
42 let params = new HttpParams()
43 params = this.restService.addRestGetParams(params, pagination, sort)
44
45 if (search) {
46 params = this.buildParamsFromSearch(search, params)
47 }
48
49 return this.authHttp.get<ResultList<AdminAbuse>>(url, { params })
50 .pipe(
51 catchError(res => this.restExtractor.handleError(res))
52 )
53 }
54
55 getUserAbuses (options: {
56 pagination: RestPagination,
57 sort: SortMeta,
58 search?: string
59 }): Observable<ResultList<UserAbuse>> {
60 const { pagination, sort, search } = options
61 const url = AbuseService.BASE_MY_ABUSE_URL
62
63 let params = new HttpParams()
64 params = this.restService.addRestGetParams(params, pagination, sort)
65
66 if (search) {
67 params = this.buildParamsFromSearch(search, params)
68 }
69
70 return this.authHttp.get<ResultList<UserAbuse>>(url, { params })
71 .pipe(
72 catchError(res => this.restExtractor.handleError(res))
73 )
74 }
75
76 reportVideo (parameters: AbuseCreate) {
77 const url = AbuseService.BASE_ABUSE_URL
78
79 const body = omit(parameters, ['id'])
80
81 return this.authHttp.post(url, body)
82 .pipe(
83 map(this.restExtractor.extractDataBool),
84 catchError(res => this.restExtractor.handleError(res))
85 )
86 }
87
88 updateAbuse (abuse: AdminAbuse, abuseUpdate: AbuseUpdate) {
89 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id
90
91 return this.authHttp.put(url, abuseUpdate)
92 .pipe(
93 map(this.restExtractor.extractDataBool),
94 catchError(res => this.restExtractor.handleError(res))
95 )
96 }
97
98 removeAbuse (abuse: AdminAbuse) {
99 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id
100
101 return this.authHttp.delete(url)
102 .pipe(
103 map(this.restExtractor.extractDataBool),
104 catchError(res => this.restExtractor.handleError(res))
105 )
106 }
107
108 addAbuseMessage (abuse: UserAbuse, message: string) {
109 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id + '/messages'
110
111 return this.authHttp.post(url, { message })
112 .pipe(
113 map(this.restExtractor.extractDataBool),
114 catchError(res => this.restExtractor.handleError(res))
115 )
116 }
117
118 listAbuseMessages (abuse: UserAbuse) {
119 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id + '/messages'
120
121 return this.authHttp.get<ResultList<AbuseMessage>>(url)
122 .pipe(
123 catchError(res => this.restExtractor.handleError(res))
124 )
125 }
126
127 deleteAbuseMessage (abuse: UserAbuse, abuseMessage: AbuseMessage) {
128 const url = AbuseService.BASE_ABUSE_URL + '/' + abuse.id + '/messages/' + abuseMessage.id
129
130 return this.authHttp.delete(url)
131 .pipe(
132 map(this.restExtractor.extractDataBool),
133 catchError(res => this.restExtractor.handleError(res))
134 )
135 }
136
137 getPrefefinedReasons (type: AbuseFilter) {
138 let reasons: { id: AbusePredefinedReasonsString, label: string, description?: string, help?: string }[] = [
139 {
140 id: 'violentOrRepulsive',
141 label: this.i18n('Violent or repulsive'),
142 help: this.i18n('Contains offensive, violent, or coarse language or iconography.')
143 },
144 {
145 id: 'hatefulOrAbusive',
146 label: this.i18n('Hateful or abusive'),
147 help: this.i18n('Contains abusive, racist or sexist language or iconography.')
148 },
149 {
150 id: 'spamOrMisleading',
151 label: this.i18n('Spam, ad or false news'),
152 help: this.i18n('Contains marketing, spam, purposefully deceitful news, or otherwise misleading thumbnail/text/tags. Please provide reputable sources to report hoaxes.')
153 },
154 {
155 id: 'privacy',
156 label: this.i18n('Privacy breach or doxxing'),
157 help: this.i18n('Contains personal information that could be used to track, identify, contact or impersonate someone (e.g. name, address, phone number, email, or credit card details).')
158 },
159 {
160 id: 'rights',
161 label: this.i18n('Copyright'),
162 help: this.i18n('Infringes your copyright wrt. the regional laws with which the server must comply.')
163 },
164 {
165 id: 'serverRules',
166 label: this.i18n('Breaks server rules'),
167 description: this.i18n('Anything not included in the above that breaks the terms of service, code of conduct, or general rules in place on the server.')
168 }
169 ]
170
171 if (type === 'video') {
172 reasons = reasons.concat([
173 {
174 id: 'thumbnails',
175 label: this.i18n('Thumbnails'),
176 help: this.i18n('The above can only be seen in thumbnails.')
177 },
178 {
179 id: 'captions',
180 label: this.i18n('Captions'),
181 help: this.i18n('The above can only be seen in captions (please describe which).')
182 }
183 ])
184 }
185
186 return reasons
187 }
188
189 private buildParamsFromSearch (search: string, params: HttpParams) {
190 const filters = this.restService.parseQueryStringFilter(search, {
191 id: { prefix: '#' },
192 state: {
193 prefix: 'state:',
194 handler: v => {
195 if (v === 'accepted') return AbuseState.ACCEPTED
196 if (v === 'pending') return AbuseState.PENDING
197 if (v === 'rejected') return AbuseState.REJECTED
198
199 return undefined
200 }
201 },
202 videoIs: {
203 prefix: 'videoIs:',
204 handler: v => {
205 if (v === 'deleted') return v
206 if (v === 'blacklisted') return v
207
208 return undefined
209 }
210 },
211 searchReporter: { prefix: 'reporter:' },
212 searchReportee: { prefix: 'reportee:' },
213 predefinedReason: { prefix: 'tag:' }
214 })
215
216 return this.restService.addObjectParams(params, filters)
217 }
218 }