MGLDZM commited on
Commit
ea0a765
·
1 Parent(s): 190cf4b
Files changed (5) hide show
  1. main.py +17 -3
  2. modules/model.py +11 -3
  3. modules/security.py +16 -2
  4. static/js/chatHandler.js +28 -1
  5. templates/main.html +50 -45
main.py CHANGED
@@ -5,6 +5,7 @@ import os, json
5
  import time
6
  from hashlib import sha256
7
  from modules import model, oauth, security, log_module, llm, chat_functions, settings
 
8
  from fastapi.staticfiles import StaticFiles
9
  from fastapi.templating import Jinja2Templates
10
  from datetime import datetime
@@ -19,11 +20,11 @@ log_module.log_write("master", "iniciado", "-")
19
 
20
  ########################## MAIN ##########################
21
  @app.get("/", response_class=HTMLResponse)
22
- async def main_page(request: Request, user = Depends(model.User.find_from_cookie)):
23
  if not user.can_use("chat"):
24
  return RedirectResponse(url='/hold')
25
 
26
- tools = [{"name": k, "desc": v} for k, v in chat_functions.function_user_text.items() ]
27
  token = user.create_token()
28
  response = templates.TemplateResponse(
29
  "main.html", {
@@ -67,12 +68,25 @@ async def get_configs(request: Request, user = Depends(model.User.find_from_head
67
  return user.configs.model_dump() | {"tokens": tokens}
68
 
69
  @app.post("/setConfigs")
70
- async def set_configs(request: Request, configs: model.Configs, user = Depends(model.User.find_from_header)):
71
  user.configs = configs
72
  user.update()
73
  return {"success":True}
74
 
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  @app.post("/chat")
77
  async def chat_async(request: Request, body: model.Chat, user = Depends(model.User.find_from_header)):
78
  if(len(body.messages) < 1 or body.messages[-1].content==""):
 
5
  import time
6
  from hashlib import sha256
7
  from modules import model, oauth, security, log_module, llm, chat_functions, settings
8
+ from modules.model import User
9
  from fastapi.staticfiles import StaticFiles
10
  from fastapi.templating import Jinja2Templates
11
  from datetime import datetime
 
20
 
21
  ########################## MAIN ##########################
22
  @app.get("/", response_class=HTMLResponse)
23
+ async def main_page(request: Request, user: User = Depends(User.find_from_cookie)):
24
  if not user.can_use("chat"):
25
  return RedirectResponse(url='/hold')
26
 
27
+ tools = [{"name": k, "desc": v} for k, v in chat_functions.function_user_text.items()]
28
  token = user.create_token()
29
  response = templates.TemplateResponse(
30
  "main.html", {
 
68
  return user.configs.model_dump() | {"tokens": tokens}
69
 
70
  @app.post("/setConfigs")
71
+ async def set_configs(request: Request, configs: model.Configs, user = Depends(User.find_from_header)):
72
  user.configs = configs
73
  user.update()
74
  return {"success":True}
75
 
76
 
77
+ @app.post("/getToken")
78
+ async def get_token(request: Request, data: dict, user: User = Depends(User.find_from_header)):
79
+ user.session = model.Session(**data)
80
+ data.pop("fingerprint")
81
+ security.validate_signature(**data)
82
+ security.create_jwt_token(data)
83
+ token = user.create_token()
84
+ class Session(BaseModel):
85
+ gid: str
86
+ fingerprint: str
87
+ public_key: str
88
+ return {"su":True}
89
+
90
  @app.post("/chat")
91
  async def chat_async(request: Request, body: model.Chat, user = Depends(model.User.find_from_header)):
92
  if(len(body.messages) < 1 or body.messages[-1].content==""):
modules/model.py CHANGED
@@ -62,11 +62,14 @@ class Chat(BaseModel):
62
 
63
  class Session(BaseModel):
64
  gid: str
65
- fprint: str
 
66
  guid: str = str(uuid.uuid4())
67
  created: datetime = datetime.now(tz)
68
  updated: datetime = datetime.now(tz)
69
  expire: datetime = datetime.now(tz)+timedelta(days=7)
 
 
70
 
71
  @classmethod
72
  def remove_expired(cls: Self, gid: str) -> None:
@@ -164,8 +167,13 @@ class User(BaseModel):
164
 
165
 
166
  def create_token(self: Self) -> str:
167
- return security.create_jwt_token({"gid": self.gid, "guid": self.session.guid})
168
-
 
 
 
 
 
169
 
170
  def update_description(self: Self, message: str) -> None:
171
  log_module.logger.info(f"Description Updated: {self.gid}")
 
62
 
63
  class Session(BaseModel):
64
  gid: str
65
+ fingerprint: str
66
+ public_key: str
67
  guid: str = str(uuid.uuid4())
68
  created: datetime = datetime.now(tz)
69
  updated: datetime = datetime.now(tz)
70
  expire: datetime = datetime.now(tz)+timedelta(days=7)
71
+
72
+
73
 
74
  @classmethod
75
  def remove_expired(cls: Self, gid: str) -> None:
 
167
 
168
 
169
  def create_token(self: Self) -> str:
170
+ return security.create_jwt_token({
171
+ "gid": self.gid,
172
+ "guid": self.session.guid,
173
+ "fp": self.session.fprint,
174
+ "pubk": self.session.public_key
175
+ })
176
+
177
 
178
  def update_description(self: Self, message: str) -> None:
179
  log_module.logger.info(f"Description Updated: {self.gid}")
modules/security.py CHANGED
@@ -5,7 +5,10 @@ from fastapi.security import HTTPBasicCredentials
5
  from fastapi.responses import RedirectResponse
6
  from . import log_module, settings
7
  from datetime import datetime, timedelta
8
-
 
 
 
9
 
10
 
11
  for key in settings.USERS:
@@ -66,4 +69,15 @@ def raise_307():
66
  status_code=status.HTTP_307_TEMPORARY_REDIRECT,
67
  detail="Could not validate access",
68
  headers=headers
69
- )
 
 
 
 
 
 
 
 
 
 
 
 
5
  from fastapi.responses import RedirectResponse
6
  from . import log_module, settings
7
  from datetime import datetime, timedelta
8
+ from Crypto.Signature import pss
9
+ from Crypto.Hash import SHA256
10
+ from Crypto.PublicKey import RSA
11
+ import base64
12
 
13
 
14
  for key in settings.USERS:
 
69
  status_code=status.HTTP_307_TEMPORARY_REDIRECT,
70
  detail="Could not validate access",
71
  headers=headers
72
+ )
73
+
74
+ def validate_signature(public_key: str, signature: str, data:str) -> bool:
75
+ public_key = RSA.import_key(public_key)
76
+ signature = base64.b64decode(signature)
77
+ data_ = SHA256.new(data.encode())
78
+ try:
79
+ pss.new(public_key).verify(data_, signature)
80
+ return True
81
+ except ValueError:
82
+ return False
83
+
static/js/chatHandler.js CHANGED
@@ -32,9 +32,13 @@ class ChatGPT{
32
  token = null;
33
  windowHandlers = {}
34
 
35
- constructor(token){
36
  // Token JWT de ejecución
37
  this.token = token;
 
 
 
 
38
 
39
  this.cargarConfigs();
40
 
@@ -43,6 +47,29 @@ class ChatGPT{
43
 
44
  this.cargarChats()
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
 
48
  cargarEventos(){
 
32
  token = null;
33
  windowHandlers = {}
34
 
35
+ constructor(token, fp, exportKey, tokenSigned){
36
  // Token JWT de ejecución
37
  this.token = token;
38
+ this.fp = fp
39
+ this.pubk = exportKey
40
+ this.tokenSigned = tokenSigned
41
+ this.obtenerToken()
42
 
43
  this.cargarConfigs();
44
 
 
47
 
48
  this.cargarChats()
49
 
50
+ }
51
+
52
+ obtenerToken(){
53
+ let data = {
54
+ fingerprint: this.fp,
55
+ public_key: this.pubk,
56
+ signature: this.tokenSigned,
57
+ data: this.token
58
+ }
59
+
60
+ $.ajax({
61
+ method: "POST",
62
+ url: "/getToken",
63
+ headers: {
64
+ "Autorization": "Bearer " + this.token,
65
+ 'Content-Type': 'application/json',
66
+ },
67
+ data: JSON.stringify(data),
68
+ timeout: 5000,
69
+ dataType: "json"
70
+ })
71
+
72
+
73
  }
74
 
75
  cargarEventos(){
templates/main.html CHANGED
@@ -173,61 +173,66 @@
173
  </dialog>
174
 
175
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
 
 
177
 
 
 
 
 
 
 
 
 
178
  var cHand;
179
  let versionLocal = localStorage.getItem("version")
180
  let versionRemota = "{{ version }}"
 
 
 
 
 
 
181
 
182
 
183
  $(document).ready(function() {
184
 
 
 
 
 
 
 
185
 
186
- let x1 = window.crypto.subtle.generateKey(
187
- {
188
- name: "RSA-PSS",
189
- modulusLength: 1024,
190
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
191
- hash: {name: "SHA-256"},
192
- },
193
- false,
194
- ["sign"]
195
- )
196
-
197
- let x2 = x1.then(keypair =>{
198
- this.keypair = keypair;
199
- return window.crypto.subtle.exportKey(
200
- "spki",
201
- keypair.publicKey
202
- )})
203
-
204
- let x3 = x2.then(exportedKey => {
205
- this.exportedKey = exportedKey;
206
- let c = window.crypto.subtle.sign(
207
- {
208
- name: "RSA-PSS",
209
- saltLength: 128,
210
- },
211
- this.keypair.privateKey,
212
- new TextEncoder().encode("{{ token }}")
213
- );
214
- return c;
215
-
216
- })
217
-
218
- x3.catch(e => {
219
- console.log(e)
220
- }).finally(y => {
221
- console.log( y)
222
- })
223
- console.log(x1)
224
- console.log(x2)
225
- console.log(x3)
226
-
227
- // .then(sign_ba => {
228
- // let sign_u8 = new Uint8Array(sign_ba);
229
- // return btoa(String.fromCharCode(...sign_u8));
230
- // }).then(sign => {
231
  // console.log("exportedKey");
232
  // console.log(this.exportedKey);
233
  // console.log("sign");
 
173
  </dialog>
174
 
175
  <script>
176
+ async function generatex(){
177
+ let keypair = await window.crypto.subtle.generateKey(
178
+ {
179
+ name: "RSA-PSS",
180
+ modulusLength: 1024,
181
+ publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
182
+ hash: {name: "SHA-256"},
183
+ },
184
+ false,
185
+ ["sign"]
186
+ )
187
+ let exportKey_ba = await window.crypto.subtle.exportKey(
188
+ "spki",
189
+ keypair.publicKey
190
+ )
191
+ let encoder = new TextEncoder()
192
+ let sign_ba = await window.crypto.subtle.sign(
193
+ {
194
+ name: "RSA-PSS",
195
+ saltLength: 32,
196
+ },
197
+ keypair.privateKey,
198
+ encoder.encode("{{ token }}")
199
+ )
200
+ let sign_u8 = new Uint8Array(sign_ba);
201
+ let sign = btoa(String.fromCharCode(...sign_u8))
202
 
203
+ let exportKey_u8 = new Uint8Array(exportKey_ba);
204
+ let exportKey = "-----BEGIN PUBLIC KEY-----\n"+btoa(String.fromCharCode(...exportKey_u8))+"\n-----END PUBLIC KEY-----"
205
 
206
+ console.log("exportedKey");
207
+ console.log(exportKey);
208
+ console.log("sign");
209
+ console.log(sign);
210
+
211
+ const fpPromise = await import('/static/js/fingerprintv4.js').then(FingerprintJS => FingerprintJS.load())
212
+ const fp = await fpPromise.get()
213
+ console.log(fp.visitorId)
214
  var cHand;
215
  let versionLocal = localStorage.getItem("version")
216
  let versionRemota = "{{ version }}"
217
+ cHand = new ChatGPT("{{ token }}", fp.visitorId, exportKey, sign);
218
+
219
+ }
220
+ generatex()
221
+
222
+
223
 
224
 
225
  $(document).ready(function() {
226
 
227
+ // let x1 = .then(keypair =>{
228
+ // .then(exportedKey => {
229
+ // return
230
+ // ).then(sign_ba =>
231
+ // })
232
+ // })
233
 
234
+ // console.log(x1)
235
+ // .then(sign => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  // console.log("exportedKey");
237
  // console.log(this.exportedKey);
238
  // console.log("sign");