From 01bd4e4948d86799634a4fba1574965afa87bdf0 Mon Sep 17 00:00:00 2001 From: "nise.moe" Date: Sun, 18 Feb 2024 14:25:14 +0100 Subject: [PATCH] Implemented slider end release times and keypress release times, along with a privileged auth system --- .../com/nisemoe/generated/tables/Users.kt | 15 ++-- .../generated/tables/records/UsersRecord.kt | 32 ++++++-- .../main/kotlin/com/nisemoe/nise/Models.kt | 10 ++- .../com/nisemoe/nise/database/ScoreService.kt | 76 ++++++++++++++++++- .../com/nisemoe/nise/service/AuthService.kt | 19 ++++- .../db/migration/V0.0.1.016__alter_users.sql | 2 + nise-frontend/src/app/app.component.html | 2 +- nise-frontend/src/app/app.module.ts | 6 +- nise-frontend/src/app/home/home.component.ts | 2 +- nise-frontend/src/app/replays.ts | 8 ++ .../app/view-score/view-score.component.html | 32 +++++++- .../app/view-score/view-score.component.ts | 34 ++++++++- .../view-similar-replays.component.ts | 2 +- .../view-suspicious-scores.component.ts | 2 +- .../src/corelib/nise-http.interceptor.ts | 17 +++++ .../{ => service}/local-cache.service.ts | 0 .../src/corelib/service/user.service.ts | 9 +-- 17 files changed, 232 insertions(+), 36 deletions(-) create mode 100644 nise-backend/src/main/resources/db/migration/V0.0.1.016__alter_users.sql create mode 100644 nise-frontend/src/corelib/nise-http.interceptor.ts rename nise-frontend/src/corelib/{ => service}/local-cache.service.ts (100%) diff --git a/nise-backend/src/main/kotlin/com/nisemoe/generated/tables/Users.kt b/nise-backend/src/main/kotlin/com/nisemoe/generated/tables/Users.kt index 0cb8f83..13d59d3 100644 --- a/nise-backend/src/main/kotlin/com/nisemoe/generated/tables/Users.kt +++ b/nise-backend/src/main/kotlin/com/nisemoe/generated/tables/Users.kt @@ -16,7 +16,7 @@ import org.jooq.ForeignKey import org.jooq.Name import org.jooq.Record import org.jooq.Records -import org.jooq.Row16 +import org.jooq.Row17 import org.jooq.Schema import org.jooq.SelectField import org.jooq.Table @@ -142,6 +142,11 @@ open class Users( */ val SYS_LAST_UPDATE: TableField = createField(DSL.name("sys_last_update"), SQLDataType.LOCALDATETIME(6), this, "") + /** + * The column public.users.is_admin. + */ + val IS_ADMIN: TableField = createField(DSL.name("is_admin"), SQLDataType.BOOLEAN.defaultValue(DSL.field(DSL.raw("false"), SQLDataType.BOOLEAN)), this, "") + private constructor(alias: Name, aliased: Table?): this(alias, null, null, aliased, null) private constructor(alias: Name, aliased: Table?, parameters: Array?>?): this(alias, null, null, aliased, parameters) @@ -183,18 +188,18 @@ open class Users( override fun rename(name: Table<*>): Users = Users(name.getQualifiedName(), null) // ------------------------------------------------------------------------- - // Row16 type methods + // Row17 type methods // ------------------------------------------------------------------------- - override fun fieldsRow(): Row16 = super.fieldsRow() as Row16 + override fun fieldsRow(): Row17 = super.fieldsRow() as Row17 /** * Convenience mapping calling {@link SelectField#convertFrom(Function)}. */ - fun mapping(from: (Long?, String?, LocalDateTime?, String?, Long?, Long?, Double?, Double?, Long?, Long?, Long?, Long?, Long?, Long?, Long?, LocalDateTime?) -> U): SelectField = convertFrom(Records.mapping(from)) + fun mapping(from: (Long?, String?, LocalDateTime?, String?, Long?, Long?, Double?, Double?, Long?, Long?, Long?, Long?, Long?, Long?, Long?, LocalDateTime?, Boolean?) -> U): SelectField = convertFrom(Records.mapping(from)) /** * Convenience mapping calling {@link SelectField#convertFrom(Class, * Function)}. */ - fun mapping(toType: Class, from: (Long?, String?, LocalDateTime?, String?, Long?, Long?, Double?, Double?, Long?, Long?, Long?, Long?, Long?, Long?, Long?, LocalDateTime?) -> U): SelectField = convertFrom(toType, Records.mapping(from)) + fun mapping(toType: Class, from: (Long?, String?, LocalDateTime?, String?, Long?, Long?, Double?, Double?, Long?, Long?, Long?, Long?, Long?, Long?, Long?, LocalDateTime?, Boolean?) -> U): SelectField = convertFrom(toType, Records.mapping(from)) } diff --git a/nise-backend/src/main/kotlin/com/nisemoe/generated/tables/records/UsersRecord.kt b/nise-backend/src/main/kotlin/com/nisemoe/generated/tables/records/UsersRecord.kt index 05cb081..97f0000 100644 --- a/nise-backend/src/main/kotlin/com/nisemoe/generated/tables/records/UsersRecord.kt +++ b/nise-backend/src/main/kotlin/com/nisemoe/generated/tables/records/UsersRecord.kt @@ -10,8 +10,8 @@ import java.time.LocalDateTime import org.jooq.Field import org.jooq.Record1 -import org.jooq.Record16 -import org.jooq.Row16 +import org.jooq.Record17 +import org.jooq.Row17 import org.jooq.impl.UpdatableRecordImpl @@ -19,7 +19,7 @@ import org.jooq.impl.UpdatableRecordImpl * This class is generated by jOOQ. */ @Suppress("UNCHECKED_CAST") -open class UsersRecord private constructor() : UpdatableRecordImpl(Users.USERS), Record16 { +open class UsersRecord private constructor() : UpdatableRecordImpl(Users.USERS), Record17 { open var userId: Long? set(value): Unit = set(0, value) @@ -85,6 +85,12 @@ open class UsersRecord private constructor() : UpdatableRecordImpl( set(value): Unit = set(15, value) get(): LocalDateTime? = get(15) as LocalDateTime? + @Suppress("INAPPLICABLE_JVM_NAME") + @set:JvmName("setIsAdmin") + open var isAdmin: Boolean? + set(value): Unit = set(16, value) + get(): Boolean? = get(16) as Boolean? + // ------------------------------------------------------------------------- // Primary key information // ------------------------------------------------------------------------- @@ -92,11 +98,11 @@ open class UsersRecord private constructor() : UpdatableRecordImpl( override fun key(): Record1 = super.key() as Record1 // ------------------------------------------------------------------------- - // Record16 type implementation + // Record17 type implementation // ------------------------------------------------------------------------- - override fun fieldsRow(): Row16 = super.fieldsRow() as Row16 - override fun valuesRow(): Row16 = super.valuesRow() as Row16 + override fun fieldsRow(): Row17 = super.fieldsRow() as Row17 + override fun valuesRow(): Row17 = super.valuesRow() as Row17 override fun field1(): Field = Users.USERS.USER_ID override fun field2(): Field = Users.USERS.USERNAME override fun field3(): Field = Users.USERS.JOIN_DATE @@ -113,6 +119,7 @@ open class UsersRecord private constructor() : UpdatableRecordImpl( override fun field14(): Field = Users.USERS.COUNT_300 override fun field15(): Field = Users.USERS.COUNT_50 override fun field16(): Field = Users.USERS.SYS_LAST_UPDATE + override fun field17(): Field = Users.USERS.IS_ADMIN override fun component1(): Long? = userId override fun component2(): String? = username override fun component3(): LocalDateTime? = joinDate @@ -129,6 +136,7 @@ open class UsersRecord private constructor() : UpdatableRecordImpl( override fun component14(): Long? = count_300 override fun component15(): Long? = count_50 override fun component16(): LocalDateTime? = sysLastUpdate + override fun component17(): Boolean? = isAdmin override fun value1(): Long? = userId override fun value2(): String? = username override fun value3(): LocalDateTime? = joinDate @@ -145,6 +153,7 @@ open class UsersRecord private constructor() : UpdatableRecordImpl( override fun value14(): Long? = count_300 override fun value15(): Long? = count_50 override fun value16(): LocalDateTime? = sysLastUpdate + override fun value17(): Boolean? = isAdmin override fun value1(value: Long?): UsersRecord { set(0, value) @@ -226,7 +235,12 @@ open class UsersRecord private constructor() : UpdatableRecordImpl( return this } - override fun values(value1: Long?, value2: String?, value3: LocalDateTime?, value4: String?, value5: Long?, value6: Long?, value7: Double?, value8: Double?, value9: Long?, value10: Long?, value11: Long?, value12: Long?, value13: Long?, value14: Long?, value15: Long?, value16: LocalDateTime?): UsersRecord { + override fun value17(value: Boolean?): UsersRecord { + set(16, value) + return this + } + + override fun values(value1: Long?, value2: String?, value3: LocalDateTime?, value4: String?, value5: Long?, value6: Long?, value7: Double?, value8: Double?, value9: Long?, value10: Long?, value11: Long?, value12: Long?, value13: Long?, value14: Long?, value15: Long?, value16: LocalDateTime?, value17: Boolean?): UsersRecord { this.value1(value1) this.value2(value2) this.value3(value3) @@ -243,13 +257,14 @@ open class UsersRecord private constructor() : UpdatableRecordImpl( this.value14(value14) this.value15(value15) this.value16(value16) + this.value17(value17) return this } /** * Create a detached, initialised UsersRecord */ - constructor(userId: Long? = null, username: String? = null, joinDate: LocalDateTime? = null, country: String? = null, countryRank: Long? = null, rank: Long? = null, ppRaw: Double? = null, accuracy: Double? = null, playcount: Long? = null, totalScore: Long? = null, rankedScore: Long? = null, secondsPlayed: Long? = null, count_100: Long? = null, count_300: Long? = null, count_50: Long? = null, sysLastUpdate: LocalDateTime? = null): this() { + constructor(userId: Long? = null, username: String? = null, joinDate: LocalDateTime? = null, country: String? = null, countryRank: Long? = null, rank: Long? = null, ppRaw: Double? = null, accuracy: Double? = null, playcount: Long? = null, totalScore: Long? = null, rankedScore: Long? = null, secondsPlayed: Long? = null, count_100: Long? = null, count_300: Long? = null, count_50: Long? = null, sysLastUpdate: LocalDateTime? = null, isAdmin: Boolean? = null): this() { this.userId = userId this.username = username this.joinDate = joinDate @@ -266,6 +281,7 @@ open class UsersRecord private constructor() : UpdatableRecordImpl( this.count_300 = count_300 this.count_50 = count_50 this.sysLastUpdate = sysLastUpdate + this.isAdmin = isAdmin resetChangedOnNotNull() } } diff --git a/nise-backend/src/main/kotlin/com/nisemoe/nise/Models.kt b/nise-backend/src/main/kotlin/com/nisemoe/nise/Models.kt index a0735e6..747f0c3 100644 --- a/nise-backend/src/main/kotlin/com/nisemoe/nise/Models.kt +++ b/nise-backend/src/main/kotlin/com/nisemoe/nise/Models.kt @@ -69,6 +69,13 @@ data class ReplayPair( val statistics: ReplayPairStatistics ) +data class ReplayDataChart( + val title: String, + val tableSamples: Int, + val table: List>, + val data: List> +) + data class ReplayData( val replay_id: Long, val user_id: Int, @@ -121,7 +128,8 @@ data class ReplayData( val count_50: Int, val count_miss: Int, - val error_distribution: Map + val error_distribution: Map, + val charts: List ) { fun calculateAccuracy(): Double { diff --git a/nise-backend/src/main/kotlin/com/nisemoe/nise/database/ScoreService.kt b/nise-backend/src/main/kotlin/com/nisemoe/nise/database/ScoreService.kt index c922b4a..d2f3237 100644 --- a/nise-backend/src/main/kotlin/com/nisemoe/nise/database/ScoreService.kt +++ b/nise-backend/src/main/kotlin/com/nisemoe/nise/database/ScoreService.kt @@ -4,13 +4,13 @@ import com.nisemoe.generated.tables.records.ScoresJudgementsRecord import com.nisemoe.generated.tables.references.* import com.nisemoe.nise.* import com.nisemoe.nise.osu.Mod +import com.nisemoe.nise.service.AuthService import org.jooq.Condition import org.jooq.DSLContext import org.jooq.Record import org.jooq.Result import org.jooq.impl.DSL import org.jooq.impl.DSL.avg -import org.springframework.cache.annotation.Cacheable import org.springframework.stereotype.Service import java.time.LocalDateTime import kotlin.math.roundToInt @@ -18,7 +18,8 @@ import kotlin.math.roundToInt @Service class ScoreService( private val dslContext: DSLContext, - private val beatmapService: BeatmapService + private val beatmapService: BeatmapService, + private val authService: AuthService ) { companion object { @@ -30,6 +31,75 @@ class ScoreService( } + fun getCharts(db: Record): List { + // We only return additional charts if the user is an admin. + if (!authService.isAdmin()) { + return emptyList() + } + + // Slider end chart + val sliderEndData = db.get(SCORES.SLIDEREND_RELEASE_TIMES)!! + .filterNotNull() + val sliderFrequencyData: List> = sliderEndData + .groupingBy { it } + .eachCount() + .map { (value, count) -> Pair(value, count / sliderEndData.size.toDouble() * 100) } + + // Slider end table + val sliderEndTable = mutableListOf>() + + sliderEndTable.add(Triple( + "Median", + String.format("%.2f", db.get(SCORES.SLIDEREND_RELEASE_MEDIAN)), + String.format("%.2f", db.get(SCORES.SLIDEREND_RELEASE_MEDIAN_ADJUSTED)) + )) + sliderEndTable.add(Triple( + "Std. deviation", + String.format("%.2f", db.get(SCORES.SLIDEREND_RELEASE_STANDARD_DEVIATION)), + String.format("%.2f", db.get(SCORES.SLIDEREND_RELEASE_STANDARD_DEVIATION_ADJUSTED)) + )) + + val sliderEndChart = ReplayDataChart( + title = "slider end release times", + tableSamples = 0, + table = sliderEndTable, + data = sliderFrequencyData + ) + + // -------------------- + + // Slider end chart + val keypressData = db.get(SCORES.KEYPRESSES_TIMES)!! + .filterNotNull() + val keypressFrequencyData: List> = keypressData + .groupingBy { it } + .eachCount() + .map { (value, count) -> Pair(value, count / keypressData.size.toDouble() * 100) } + + // Slider end table + val keypressTable = mutableListOf>() + + keypressTable.add(Triple( + "Median", + String.format("%.2f", db.get(SCORES.KEYPRESSES_MEDIAN)), + String.format("%.2f", db.get(SCORES.KEYPRESSES_MEDIAN_ADJUSTED)) + )) + keypressTable.add(Triple( + "Std. deviation", + String.format("%.2f", db.get(SCORES.KEYPRESSES_STANDARD_DEVIATION)), + String.format("%.2f", db.get(SCORES.KEYPRESSES_STANDARD_DEVIATION_ADJUSTED)) + )) + + val keypressChart = ReplayDataChart( + title = "keypress release times", + tableSamples = 0, + table = keypressTable, + data = keypressFrequencyData + ) + + return listOf(sliderEndChart, keypressChart) + } + fun getReplayData(replayId: Long): ReplayData? { val result = dslContext.select(DSL.asterisk()) .from(SCORES) @@ -41,6 +111,7 @@ class ScoreService( val beatmapId = result.get(BEATMAPS.BEATMAP_ID, Int::class.java) val averageUR = beatmapService.getAverageUR(beatmapId = beatmapId, excludeReplayId = replayId) val hitDistribution = this.getHitDistribution(scoreId = result.get(SCORES.ID, Int::class.java)) + val charts = this.getCharts(result) val replayData = ReplayData( replay_id = replayId, @@ -80,6 +151,7 @@ class ScoreService( error_coefficient_of_variation = result.get(SCORES.ERROR_COEFFICIENT_OF_VARIATION, Double::class.java), error_kurtosis = result.get(SCORES.ERROR_KURTOSIS, Double::class.java), error_skewness = result.get(SCORES.ERROR_SKEWNESS, Double::class.java), + charts = charts ) this.loadComparableReplayData(replayData) return replayData diff --git a/nise-backend/src/main/kotlin/com/nisemoe/nise/service/AuthService.kt b/nise-backend/src/main/kotlin/com/nisemoe/nise/service/AuthService.kt index 8afe05e..8cacd1c 100644 --- a/nise-backend/src/main/kotlin/com/nisemoe/nise/service/AuthService.kt +++ b/nise-backend/src/main/kotlin/com/nisemoe/nise/service/AuthService.kt @@ -1,18 +1,30 @@ package com.nisemoe.nise.service +import com.nisemoe.generated.tables.references.USERS +import org.jooq.DSLContext import org.springframework.security.authentication.AnonymousAuthenticationToken import org.springframework.security.core.context.SecurityContextHolder import org.springframework.security.oauth2.core.user.DefaultOAuth2User import org.springframework.stereotype.Service @Service -class AuthService { +class AuthService( + private val dslContext: DSLContext +) { data class UserInfo( - val userId: Int, + val userId: Long, val username: String ) + fun isAdmin(): Boolean { + if(!this.isLoggedIn()) + return false + + val currentUser = this.getCurrentUser() + return dslContext.fetchExists(USERS, USERS.USER_ID.eq(currentUser.userId).and(USERS.IS_ADMIN)) + } + fun isLoggedIn(): Boolean { val authentication = SecurityContextHolder.getContext().authentication return !(authentication == null || authentication is AnonymousAuthenticationToken || authentication.principal == null) @@ -26,10 +38,9 @@ class AuthService { val userDetails = authentication.principal as DefaultOAuth2User return UserInfo( - userId = userDetails.attributes["id"] as Int, + userId = (userDetails.attributes["id"] as Int).toLong(), username = userDetails.attributes["username"] as String ) - } } \ No newline at end of file diff --git a/nise-backend/src/main/resources/db/migration/V0.0.1.016__alter_users.sql b/nise-backend/src/main/resources/db/migration/V0.0.1.016__alter_users.sql new file mode 100644 index 0000000..1bebb7e --- /dev/null +++ b/nise-backend/src/main/resources/db/migration/V0.0.1.016__alter_users.sql @@ -0,0 +1,2 @@ +ALTER TABLE public.users + ADD COLUMN is_admin boolean DEFAULT false; \ No newline at end of file diff --git a/nise-frontend/src/app/app.component.html b/nise-frontend/src/app/app.component.html index cfb1599..8dd5b87 100644 --- a/nise-frontend/src/app/app.component.html +++ b/nise-frontend/src/app/app.component.html @@ -26,5 +26,5 @@
- v20240217 + v20240218
diff --git a/nise-frontend/src/app/app.module.ts b/nise-frontend/src/app/app.module.ts index 27d37df..d842df3 100644 --- a/nise-frontend/src/app/app.module.ts +++ b/nise-frontend/src/app/app.module.ts @@ -3,7 +3,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; -import {HttpClientModule } from "@angular/common/http"; +import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http"; import { ViewSuspiciousScoresComponent } from './view-suspicious-scores/view-suspicious-scores.component'; import { ViewSimilarReplaysComponent } from './view-similar-replays/view-similar-replays.component'; import { HomeComponent } from './home/home.component'; @@ -12,6 +12,7 @@ import {FormsModule} from "@angular/forms"; import {NgOptimizedImage} from "@angular/common"; import {rxStompServiceFactory} from "../corelib/stomp/stomp.factory"; import {RxStompService} from "../corelib/stomp/stomp.service"; +import {NiseHttpInterceptor} from "../corelib/nise-http.interceptor"; @NgModule({ declarations: [ @@ -32,7 +33,8 @@ import {RxStompService} from "../corelib/stomp/stomp.service"; { provide: RxStompService, useFactory: rxStompServiceFactory, - } + }, + { provide: HTTP_INTERCEPTORS, useClass: NiseHttpInterceptor, multi: true } ], bootstrap: [AppComponent] }) diff --git a/nise-frontend/src/app/home/home.component.ts b/nise-frontend/src/app/home/home.component.ts index f250667..b162e84 100644 --- a/nise-frontend/src/app/home/home.component.ts +++ b/nise-frontend/src/app/home/home.component.ts @@ -1,7 +1,7 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; import {Observable, Subscription} from "rxjs"; import {environment} from "../../environments/environment"; -import {LocalCacheService} from "../../corelib/local-cache.service"; +import {LocalCacheService} from "../../corelib/service/local-cache.service"; import {RxStompService} from "../../corelib/stomp/stomp.service"; import {Message} from "@stomp/stompjs/esm6"; import {ReplayData} from "../replays"; diff --git a/nise-frontend/src/app/replays.ts b/nise-frontend/src/app/replays.ts index e6e609e..e73898e 100644 --- a/nise-frontend/src/app/replays.ts +++ b/nise-frontend/src/app/replays.ts @@ -1,3 +1,10 @@ +export interface ReplayDataChart { + title: string; + tableSamples: number; + table: Array<{ first: string, second: string, third: string }>; + data: Array<{ first: number, second: number }>; +} + export interface ReplayData { replay_id: number; user_id: number; @@ -51,6 +58,7 @@ export interface ReplayData { count_miss: number; error_distribution: ErrorDistribution; + charts: ReplayDataChart[]; } export interface DistributionEntry { diff --git a/nise-frontend/src/app/view-score/view-score.component.html b/nise-frontend/src/app/view-score/view-score.component.html index 7d66b81..d2aa880 100644 --- a/nise-frontend/src/app/view-score/view-score.component.html +++ b/nise-frontend/src/app/view-score/view-score.component.html @@ -98,7 +98,7 @@ -
+

# nerd stats

@@ -150,6 +150,36 @@
+
+

+ # {{ chart.title }} +

+ + + + + + + + + + + +
+ value + + adjusted value (no outliers) +
{{ entry.first }}{{ entry.second }}{{ entry.third }}
+ + +
+

# hit distribution

, any> { + const sortedData = chart.data.sort((a, b) => a.first - b.first); + + const minFirst = Math.floor(sortedData[0].first / 2) * 2; // Round down to nearest even number + const maxFirst = Math.ceil(sortedData[sortedData.length - 1].first / 2) * 2; // Round up to nearest even number + const groupRanges = Array.from({length: (maxFirst - minFirst) / 2 + 1}, (_, i) => minFirst + i * 2); + + const groupedData = groupRanges.map(rangeStart => { + const rangeEnd = rangeStart + 2; + const entriesInGroup = sortedData.filter(e => e.first >= rangeStart && e.first < rangeEnd); + const sumSecond = entriesInGroup.reduce((acc, curr) => acc + curr.second, 0); + return { first: rangeStart, second: sumSecond }; + }); + + const labels = groupedData.map(({ first }) => `${first}ms to ${first + 2}ms`); + const datasets = [ + { + data: groupedData.map(({ second }) => second), + label: chart.title + " (%)", + backgroundColor: 'rgba(0,255,41,0.66)', + borderRadius: 5 + } + ]; + + return { labels, datasets }; + } + + buildCircleguardUrl(): string { if(!this.replayData) { return ""; @@ -147,7 +175,7 @@ export class ViewScoreComponent implements OnInit { return filledEntries.map(([key, _]) => { const start = parseInt(String(key)); const end = start + 2; - return `${start} to ${end}ms`; + return `${start}ms to ${end}ms`; }); } diff --git a/nise-frontend/src/app/view-similar-replays/view-similar-replays.component.ts b/nise-frontend/src/app/view-similar-replays/view-similar-replays.component.ts index e5bbb53..5e9e03f 100644 --- a/nise-frontend/src/app/view-similar-replays/view-similar-replays.component.ts +++ b/nise-frontend/src/app/view-similar-replays/view-similar-replays.component.ts @@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core'; import {SimilarReplay} from "../replays"; import {Observable} from "rxjs"; import {environment} from "../../environments/environment"; -import {LocalCacheService} from "../../corelib/local-cache.service"; +import {LocalCacheService} from "../../corelib/service/local-cache.service"; import {ActivatedRoute, Router} from "@angular/router"; import {FilterManagerService} from "../filter-manager.service"; diff --git a/nise-frontend/src/app/view-suspicious-scores/view-suspicious-scores.component.ts b/nise-frontend/src/app/view-suspicious-scores/view-suspicious-scores.component.ts index edd5c77..7d2cfe7 100644 --- a/nise-frontend/src/app/view-suspicious-scores/view-suspicious-scores.component.ts +++ b/nise-frontend/src/app/view-suspicious-scores/view-suspicious-scores.component.ts @@ -2,7 +2,7 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; import {environment} from "../../environments/environment"; import {SuspiciousScore} from "../replays"; import {Observable, Subscription, timer} from 'rxjs'; -import {LocalCacheService} from "../../corelib/local-cache.service"; +import {LocalCacheService} from "../../corelib/service/local-cache.service"; import {ActivatedRoute, Router} from "@angular/router"; import {FilterManagerService} from "../filter-manager.service"; diff --git a/nise-frontend/src/corelib/nise-http.interceptor.ts b/nise-frontend/src/corelib/nise-http.interceptor.ts new file mode 100644 index 0000000..9f8bc26 --- /dev/null +++ b/nise-frontend/src/corelib/nise-http.interceptor.ts @@ -0,0 +1,17 @@ +import {Injectable} from '@angular/core'; +import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http'; +import {Observable} from 'rxjs'; + +@Injectable() +export class NiseHttpInterceptor implements HttpInterceptor { + + intercept(req: HttpRequest, next: HttpHandler): Observable> { + const modifiedReq = req.clone({ + headers: req.headers.set('X-NISE-API', '20240218'), + withCredentials: true + }); + + return next.handle(modifiedReq); + } + +} diff --git a/nise-frontend/src/corelib/local-cache.service.ts b/nise-frontend/src/corelib/service/local-cache.service.ts similarity index 100% rename from nise-frontend/src/corelib/local-cache.service.ts rename to nise-frontend/src/corelib/service/local-cache.service.ts diff --git a/nise-frontend/src/corelib/service/user.service.ts b/nise-frontend/src/corelib/service/user.service.ts index 25119cc..d8e4dc2 100644 --- a/nise-frontend/src/corelib/service/user.service.ts +++ b/nise-frontend/src/corelib/service/user.service.ts @@ -1,5 +1,5 @@ import {Injectable} from '@angular/core'; -import {HttpBackend, HttpClient} from "@angular/common/http"; +import {HttpClient} from "@angular/common/http"; import {environment} from "../../environments/environment"; interface UserInfo { @@ -12,15 +12,12 @@ interface UserInfo { }) export class UserService { - private httpClient: HttpClient; - currentUser: UserInfo | null = null; loginCallback: () => void = () => {}; logoutCallback: () => void = () => {}; - constructor(private httpBackend: HttpBackend) { - this.httpClient = new HttpClient(httpBackend); + constructor(private httpClient: HttpClient) { this.currentUser = this.loadCurrentUserFromLocalStorage(); this.updateUser() .catch(reason => console.debug(reason)); @@ -40,7 +37,7 @@ export class UserService { public updateUser(): Promise { return new Promise((resolve, reject) => { - this.httpClient.get(`${environment.apiUrl}/auth`, {withCredentials: true}) + this.httpClient.get(`${environment.apiUrl}/auth`) .subscribe({ next: (user) => { this.currentUser = user;