2
0
Эх сурвалжийг харах

улучшил проверку при оплате

kpmy 5 жил өмнө
parent
commit
ac0ac774e1

+ 3 - 4
src/app/src/app/person/person.debit.dialog.component.html

@@ -17,9 +17,8 @@
   <div style="padding-top: 1em">
     <mat-checkbox [(ngModel)]="data.limited" labelPosition="after">ограничить время действия</mat-checkbox>
   </div>
-  <div fxLayout="column" fxLayoutGap="0.5em">
-    <mat-label id="time-radio-label">Время действия</mat-label>
-    <mat-radio-group [(ngModel)]="data.time" [disabled]="!data.limited" aria-labelledby="time-radio-label" fxLayout="column" fxLayoutGap="0.2em">
+  <div fxLayout="column">
+    <mat-radio-group [(ngModel)]="data.time" [disabled]="!data.limited" fxLayout="column" fxLayoutGap="0.2em">
       <mat-radio-button [value]="1">1 час</mat-radio-button>
       <mat-radio-button [value]="3">3 часа</mat-radio-button>
       <mat-radio-button [value]="8">8 часов</mat-radio-button>
@@ -37,5 +36,5 @@
 </div>
 <div fxLayout="row" fxLayoutAlign="end center" mat-dialog-actions>
   <button (click)="getCode()" color="warn" mat-button>СОЗДАТЬ КОД</button>
-  <button [mat-dialog-close]="{data: data}" mat-button>ОТМЕНА</button>
+  <button [mat-dialog-close]="{data: data}" mat-button>ЗАКРЫТЬ</button>
 </div>

+ 3 - 2
src/app/src/app/person/person.page.component.ts

@@ -87,8 +87,9 @@ export class PersonPageComponent implements OnInit {
       ref.afterClosed().subscribe((res: any) => {
         if (res.action == 'create') {
           let data = <PersonCreditData>res.data
-          this.httpClient.post(`/api/old/person/${person.auth.id}/account/${data.account.id}/credit/by-link/${data.code}`, {amount: data.amount}).subscribe((res: any) => {
-            console.log(`transaction registered ${res.id}`)
+          this.httpClient.post(`/api/old/person/${person.auth.id}/account/${data.account.id}/credit/by-link/${data.code}`, {code: res.key, amount: data.amount}).subscribe((res: any) => {
+            this.ngOnInit()
+            console.log(`transaction done ${res.id}`)
           })
         }
       })

+ 51 - 22
src/main/kotlin/inn/ocsf/bee/freigeld/serve/rest/PersonController.kt

@@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory
 import org.springframework.context.annotation.Profile
 import org.springframework.http.HttpStatus
 import org.springframework.http.ResponseEntity
+import org.springframework.stereotype.Service
 import org.springframework.web.bind.annotation.*
 import java.time.LocalDateTime
 import java.time.ZoneId
@@ -50,6 +51,9 @@ class PersonController {
     @Inject
     private lateinit var linkRepo: PublicLinkRepository
 
+    @Inject
+    private lateinit var totp: PersonTotpService
+
     private val log = LoggerFactory.getLogger(javaClass)
 
 
@@ -71,7 +75,7 @@ class PersonController {
     @RequestMapping("api/old/person/{personId}/account/{accountId}/debit-by-link", method = [RequestMethod.POST])
     fun getDebitLink(@PathVariable("personId") personId: UUID, @PathVariable("accountId") accountId: UUID, @RequestBody lreq: DebitLinkReq): ResponseEntity<Map<String, Any>> {
         val link = linkRepo.getFreeIdAndSave { id -> PublicLinkDebitAccount(id, personId, accountId, lreq.amount, lreq.once, lreq.limited, lreq.time) }
-        return ResponseEntity.ok(mapOf("code" to link.id)) //p7do
+        return ResponseEntity.ok(mapOf("code" to link.id)) //p7do xfay
     }
 
     @RequestMapping("api/old/person/{personId}/accounts", method = [RequestMethod.GET])
@@ -120,6 +124,13 @@ class PersonController {
 
     @RequestMapping("api/old/person/{personId}/account/{accountId}/credit/by-link/{linkId}")
     fun creditMoney(@PathVariable("personId") personId: UUID, @PathVariable("accountId") accountId: UUID, @PathVariable("linkId") linkId: String, @RequestBody req: CreditLinkReq): ResponseEntity<Map<String, Any?>> {
+        val verifier = totp.getVerifier()
+        val secret = world.getPerson(personId)?.let { world.getPersonIdentitySet(it) }?.filter { it is PersonIdentitySecret }?.map { it as PersonIdentitySecret }?.firstOrNull()
+        if (secret != null) {
+            if (!verifier.isValidCode(secret.key, req.code)) {
+                return ResponseEntity(HttpStatus.FORBIDDEN)
+            }
+        }
         val fromAccount = bank.getAccounts(personId).first { it.id == accountId }
         val link = linkRepo.findById(linkId).filter { it is PublicLinkDebitAccount }.map { it as PublicLinkDebitAccount }.orElse(null)
         val ret = if (fromAccount != null) {
@@ -127,7 +138,7 @@ class PersonController {
                 val toAccount = bank.getAccount(link.accountId!!)
                 if (toAccount != null) {
                     if (req.amount != null && req.amount > 0) {
-                        bank.exchange(toAccount, fromAccount, req.amount).get()
+                        bank.exchange(toAccount, fromAccount, req.amount).get(5, TimeUnit.SECONDS)
                     } else {
                         null
                     }
@@ -148,7 +159,7 @@ class PersonController {
     }
 }
 
-data class CreditLinkReq(val amount: Long?)
+data class CreditLinkReq(val code: String?, val amount: Long?)
 
 data class DebitLinkReq(val amount: Long?, val once: Boolean?, val limited: Boolean?, val time: Long?)
 
@@ -178,6 +189,36 @@ class PublicLinkDebitAccount() : PublicLink() {
     }
 }
 
+@Service
+class PersonTotpService {
+
+    fun getVerifier(): CodeVerifier {
+        val timeProvider: TimeProvider = SystemTimeProvider()
+        val codeGenerator: CodeGenerator = DefaultCodeGenerator(HashingAlgorithm.SHA1)
+        val verifier = DefaultCodeVerifier(codeGenerator, timeProvider)
+        verifier.setTimePeriod(30)
+        verifier.setAllowedTimePeriodDiscrepancy(4)
+        return verifier
+    }
+
+    fun getSecret(): String {
+        val secretGenerator = DefaultSecretGenerator()
+        val secret = secretGenerator.generate()
+        return secret
+    }
+
+    fun getImage(secret: String): String {
+        val data = QrData.Builder().secret(secret).algorithm(HashingAlgorithm.SHA1).label("personal kalita").issuer("FreiGeld").digits(6).period(30).build()
+        val generator = ZxingPngQrGenerator()
+        val imageData = generator.generate(data)
+        val mimeType = generator.imageMimeType
+        val dataUri = getDataUriForImage(imageData, mimeType)
+        return dataUri
+    }
+
+
+}
+
 @RestController
 @CrossOrigin
 class PersonAuthController : JwtAuthenticationController() {
@@ -191,35 +232,23 @@ class PersonAuthController : JwtAuthenticationController() {
     @Inject
     private lateinit var world: GlobalWorld
 
+    @Inject
+    private lateinit var totp: PersonTotpService
+
     @RequestMapping("api/new/person/qr", method = [RequestMethod.GET])
     fun newqr(@RequestParam("siteId") siteId: UUID): ResponseEntity<QrDataResponse> {
-        val secretGenerator = DefaultSecretGenerator()
-        val secret = secretGenerator.generate()
+        val secret = totp.getSecret()
 
         storage.put(secretToSite, secret, siteId)
 
-        val data = QrData.Builder().secret(secret).algorithm(HashingAlgorithm.SHA1).label("personal kalita").issuer("FreiGeld").digits(6).period(30).build()
-
-        val generator = ZxingPngQrGenerator()
-        val imageData = generator.generate(data)
-        val mimeType = generator.imageMimeType
-        val dataUri = getDataUriForImage(imageData, mimeType)
+        val dataUri = totp.getImage(secret)
 
         return ResponseEntity.ok(QrDataResponse(secret, dataUri))
     }
 
-    private fun getVerifier(): CodeVerifier {
-        val timeProvider: TimeProvider = SystemTimeProvider()
-        val codeGenerator: CodeGenerator = DefaultCodeGenerator(HashingAlgorithm.SHA1)
-        val verifier = DefaultCodeVerifier(codeGenerator, timeProvider)
-        verifier.setTimePeriod(30)
-        verifier.setAllowedTimePeriodDiscrepancy(4)
-        return verifier
-    }
-
     @RequestMapping("api/old/person/{personId}/check6", method = [RequestMethod.POST])
     fun checkqrnow(@PathVariable("personId") personId: UUID, @RequestBody rq: QrOldSixRequest): ResponseEntity<QrOldSixResponse> {
-        val verifier = getVerifier()
+        val verifier = totp.getVerifier()
         val person = world.getPerson(personId)
         if (person != null) {
             val secret = world.getPersonIdentitySet(person)?.filter { it is PersonIdentitySecret }?.map { it as PersonIdentitySecret }?.firstOrNull()
@@ -235,7 +264,7 @@ class PersonAuthController : JwtAuthenticationController() {
 
     @RequestMapping("api/new/person/check6", method = [RequestMethod.POST])
     fun checkqr(@RequestBody req: QrSixRequest): ResponseEntity<QrSixResponse> {
-        val verifier = getVerifier()
+        val verifier = totp.getVerifier()
 
         var register = false