Skip to content

Commit

Permalink
Set up Redis persistence and registration functions
Browse files Browse the repository at this point in the history
  • Loading branch information
xdzqyyds committed Dec 8, 2024
1 parent 83c89c0 commit 6e2059d
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 21 deletions.
1 change: 1 addition & 0 deletions server/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func NewApi(rdb *redis.Client, secret string, live777Url string, live777Token st

r.Post("/user/", handle.CreateUser)
r.Post("/login/", handle.Login)
r.Post("/login/signup", handle.Signup)

//r.Post("/room/{roomId}/message", handle.CreateMessage)
//r.Get("/room/{roomId}/message", handle.ShowMessage)
Expand Down
50 changes: 50 additions & 0 deletions server/api/v1/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,53 @@ func (h *Handler) UpdateUserList(w http.ResponseWriter, r *http.Request) {
return
}
}

func (h *Handler) Signup(w http.ResponseWriter, r *http.Request) {
var signupReq LoginRequest

if err := json.NewDecoder(r.Body).Decode(&signupReq); err != nil {
log.Printf("Error decoding signup request: %v\n", err)
w.WriteHeader(http.StatusBadRequest)
render.JSON(w, r, LoginResponse{Success: false, Message: "Invalid request format"})
return
}

// User input cannot be empty
if signupReq.UserId == "" || signupReq.Password == "" {
render.JSON(w, r, LoginResponse{Success: false, Message: "User ID and password cannot be empty"})
return
}

ctx := context.Background()

// Check whether the user name already exists
exists, err := h.rdb.HExists(ctx, model.UserStorageKey, signupReq.UserId).Result()
if err != nil {
log.Printf("Error checking user existence: %v\n", err)
w.WriteHeader(http.StatusInternalServerError)
render.JSON(w, r, LoginResponse{Success: false, Message: "Internal server error"})
return
}

if exists {
render.JSON(w, r, LoginResponse{Success: false, Message: "This user ID is already registered"})
return
}

// Execute multiple Redis commands using pipes
pipe := h.rdb.Pipeline()

pipe.HSet(ctx, model.UserStorageKey, signupReq.UserId, signupReq.Password)
pipe.HSet(ctx, model.UserOnlineStatusKey, signupReq.UserId, "0")

_, err = pipe.Exec(ctx)
if err != nil {
log.Printf("Error executing pipeline for user registration: %v\n", err)
w.WriteHeader(http.StatusInternalServerError)
render.JSON(w, r, LoginResponse{Success: false, Message: "Failed to register user"})
return
}

log.Printf("New user registered successfully: %s\n", signupReq.UserId)
render.JSON(w, r, LoginResponse{Success: true, Message: "Registration successful! You can now login."})
}
23 changes: 11 additions & 12 deletions server/api/v1/room.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package v1

import (
"context"
"net/http"

"woom/server/helper"
Expand All @@ -26,17 +25,17 @@ func (h *Handler) CreateRoom(w http.ResponseWriter, r *http.Request) {
Presenter: "",
Locked: false,
}
gobAdmin, err := helper.GobEncode(&admin)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
if err := h.rdb.HSet(context.TODO(), roomId, model.AdminUniqueKey, gobAdmin).Err(); err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
// gobAdmin, err := helper.GobEncode(&admin)
// if err != nil {
// w.WriteHeader(http.StatusInternalServerError)
// w.Write([]byte(err.Error()))
// return
// }
// if err := h.rdb.HSet(context.TODO(), roomId, model.AdminUniqueKey, gobAdmin).Err(); err != nil {
// w.WriteHeader(http.StatusInternalServerError)
// w.Write([]byte(err.Error()))
// return
// }

//if _, err := h.helperCreateRoomStream(r, roomId, streamId); err != nil {
// w.WriteHeader(http.StatusInternalServerError)
Expand Down
18 changes: 16 additions & 2 deletions server/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,21 @@ func newRdbClient(url string) *redis.Client {
panic(err)
}

return redis.NewClient(opts)
client := redis.NewClient(opts)

// Configure RDB and AOF backup
ctx := context.Background()
if err := client.ConfigSet(ctx, "save", "900 1 300 10 60 10000").Err(); err != nil {
log.Printf("Failed to set RDB: %v\n", err)
}
if err := client.ConfigSet(ctx, "appendonly", "yes").Err(); err != nil {
log.Printf("Failed to set AOF: %v\n", err)
}
if err := client.ConfigSet(ctx, "appendfsync", "everysec").Err(); err != nil {
log.Printf("Failed to set AOF sync: %v\n", err)
}

return client
}

func Daemon(ctx context.Context) {
Expand All @@ -31,7 +45,7 @@ func Daemon(ctx context.Context) {
rdb := newRdbClient(cfg.RedisUrl)
log.Println(rdb)

model.ClearRedis(rdb)
//model.ClearRedis(rdb)
model.InitUserData(rdb)

handler := api.NewApi(rdb, cfg.Secret, cfg.Live777Url, cfg.Live777Token)
Expand Down
39 changes: 32 additions & 7 deletions webapp/components/login/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useState } from 'react'
import { useAtom } from 'jotai'
import { userIdAtom, userPasswordAtom, isLoggedInAtom } from '../../store/atom'
import { getLoginStatus } from '../../components/join'
import { login } from '../../lib/api'
import { login, signup } from '../../lib/api'
import { setStorage, getStorage } from '../../lib/storage'

export default function Login() {
Expand Down Expand Up @@ -33,6 +33,23 @@ export default function Login() {
}
}

const handleSignup = async () => {
if (userId === '' || password === '') {
setError('User ID and password cannot be empty')
return
}
try {
const response = await signup(userId, password)
if (response.success) {
setError('Registration successful! You can now login.')
} else {
setError(response.message || 'Registration failed')
}
} catch {
setError('Network error or server unavailable')
}
}

return (
<div className="flex flex-col justify-around bg-gray-800/80 p-6 my-4 rounded-lg">
<center className="flex flex-col items-center space-y-4">
Expand All @@ -57,12 +74,20 @@ export default function Login() {
</p>
)}

<button
className="btn-primary"
onClick={handleLogin}
>
Sign In
</button>
<div className="flex space-x-4">
<button
className="btn-primary"
onClick={handleLogin}
>
Login In
</button>
<button
className="btn-primary"
onClick={handleSignup}
>
Sign Up
</button>
</div>
</center>
</div>
)
Expand Down
12 changes: 12 additions & 0 deletions webapp/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,17 @@ async function getInvitation(inviteeId: string): Promise<InvitationResponse | nu
}
}

async function signup(userId: string, password: string): Promise<{ success: boolean; message: string }> {
const response = await fetch('/login/signup', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ userId, password }),
})
return response.json()
}

export {
setRoomId,
setApiToken,
Expand All @@ -219,6 +230,7 @@ export {
updateUserStatus,
sendInvite,
getInvitation,
signup,

StreamState,
}
Expand Down

0 comments on commit 6e2059d

Please sign in to comment.