go-cook/internal/services/refreshTokenService.go

87 lines
2.1 KiB
Go

package services
import (
"database/sql"
"errors"
"git.jamestombleson.com/jtom38/go-cook/internal/domain"
"git.jamestombleson.com/jtom38/go-cook/internal/repositories"
"github.com/google/uuid"
)
const (
ErrUnexpectedAmountOfRowsUpdated = "got a unexpected of rows updated"
)
type RefreshToken interface {
Create(username string) (string, error)
GetByName(name string) (domain.RefreshTokenEntity, error)
Delete(id int64) (int64, error)
IsRequestValid(username, refreshToken string) error
}
// A new jwt token can be made if the user has the correct refresh token for the user.
// It will also require the old JWT token so the expire time is pulled and part of the validation
type RefreshTokenService struct {
table repositories.RefreshTokenTable
}
func NewRefreshTokenService(conn *sql.DB) RefreshTokenService {
return RefreshTokenService{
table: repositories.NewRefreshTokenRepository(conn),
}
}
func (rt RefreshTokenService) Create(username string) (string, error) {
//if a refresh token already exists for a user, reuse
existingToken, err := rt.GetByName(username)
if err == nil {
rowsRemoved, err := rt.Delete(existingToken.Id)
if err != nil {
return "", err
}
if rowsRemoved != 1 {
return "", errors.New(ErrUnexpectedAmountOfRowsUpdated)
}
}
token, err := uuid.NewV7()
if err != nil {
return "", err
}
rows, err := rt.table.Create(username, token.String())
if err != nil {
return "", err
}
if rows != 1 {
return "", errors.New("expected one row but got none")
}
return token.String(), nil
}
// Find the saved refresh token for a user and return it if it exists
func (rt RefreshTokenService) GetByName(name string) (domain.RefreshTokenEntity, error) {
return rt.table.GetByUsername(name)
}
// This will request that a object is removed from the database
func (rt RefreshTokenService) Delete(id int64) (int64, error) {
return rt.table.DeleteById(id)
}
func (rt RefreshTokenService) IsRequestValid(username, refreshToken string) error {
token, err := rt.GetByName(username)
if err != nil {
return err
}
if token.Token != refreshToken {
return errors.New("the refresh token given does not match")
}
return nil
}