diff --git a/api/constants/main.go b/api/constants/main.go
new file mode 100644
index 0000000..d7abcb0
--- /dev/null
+++ b/api/constants/main.go
@@ -0,0 +1,6 @@
+package constants
+
+type env_type string
+
+const Dev env_type = "development"
+const Prod env_type = "prod"
diff --git a/api/controllers/url.go b/api/controllers/url.go
index cf636f6..de89537 100644
--- a/api/controllers/url.go
+++ b/api/controllers/url.go
@@ -155,7 +155,7 @@ func ResolveURL(w http.ResponseWriter, r *http.Request) {
return
}
- go func(r http.Request, url models.URL) {
+ go func(r *http.Request, url models.URL) {
userAgent := r.Header.Get("User-Agent")
ua := uasurfer.Parse(userAgent)
@@ -172,7 +172,7 @@ func ResolveURL(w http.ResponseWriter, r *http.Request) {
timestamp := time.Now().Unix()
helpers.Tracker.CaptureRedirectEvent(device, ip, os, referrer, urlId, timestamp)
- }(*r, *url)
+ }(r, *url)
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
http.Redirect(w, r, url.Destination, http.StatusMovedPermanently)
diff --git a/api/controllers/user.go b/api/controllers/user.go
index 689c044..2c4ceee 100644
--- a/api/controllers/user.go
+++ b/api/controllers/user.go
@@ -97,21 +97,22 @@ func CallbackSignInWithGoogle(w http.ResponseWriter, r *http.Request) {
return
}
+ var token *string
+
if user != nil {
- token, _ := utils.CreateJWT(user)
- http.Redirect(w, r, fmt.Sprintf(os.Getenv("FRONTEND_AUTH_URL")+"%v", *token), http.StatusSeeOther)
- return
+ token, _ = utils.CreateJWT(user)
} else {
user, err = models.CreateUser(googleProfile["email"].(string), googleProfile["name"].(string), googleProfile["picture"].(string))
if err != nil {
helpers.SendJSONError(w, http.StatusInternalServerError, "Internal Server Error")
return
}
- token, _ := utils.CreateJWT(user)
- http.Redirect(w, r, fmt.Sprintf(os.Getenv("FRONTEND_AUTH_URL")+"%v", *token), http.StatusSeeOther)
- return
+ token, _ = utils.CreateJWT(user)
}
+ cookie := utils.CreateAuthCookie(*token)
+ http.SetCookie(w, cookie)
+ http.Redirect(w, r, os.Getenv("FRONTEND_URL"), http.StatusSeeOther)
}
func SelfUser(w http.ResponseWriter, r *http.Request) {
diff --git a/api/helpers/helpers.go b/api/helpers/helpers.go
index d0fcc6f..6afa753 100644
--- a/api/helpers/helpers.go
+++ b/api/helpers/helpers.go
@@ -9,6 +9,8 @@ import (
"time"
)
+var ENV string
+
type ErrorResponse struct {
Error string `json:"error"`
}
diff --git a/api/helpers/urls.go b/api/helpers/urls.go
index 1535660..c454621 100644
--- a/api/helpers/urls.go
+++ b/api/helpers/urls.go
@@ -30,8 +30,7 @@ func RemoverDomainError(url string) bool {
}
func BuildUrl(url string) string {
- env := os.Getenv("ENV")
- if env == "development" {
+ if ENV == "development" {
return "http://" + os.Getenv("SHORTED_URL_DOMAIN") + url
}
return "https://" + os.Getenv("SHORTED_URL_DOMAIN") + url
diff --git a/api/main.go b/api/main.go
index 3173977..48624e4 100644
--- a/api/main.go
+++ b/api/main.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/gorilla/mux"
+ "github.com/ivinayakg/shorte.live/api/constants"
"github.com/ivinayakg/shorte.live/api/controllers"
"github.com/ivinayakg/shorte.live/api/helpers"
"github.com/ivinayakg/shorte.live/api/middleware"
@@ -56,9 +57,10 @@ func main() {
}
PORT := os.Getenv("PORT")
+ helpers.ENV = os.Getenv("ENV")
go func() {
- if os.Getenv("ENV") != "development" {
+ if os.Getenv("ENV") == string(constants.Prod) {
return
}
router := createRouter()
diff --git a/api/middleware/auth.go b/api/middleware/auth.go
index 1bf894e..2f46126 100644
--- a/api/middleware/auth.go
+++ b/api/middleware/auth.go
@@ -7,6 +7,7 @@ import (
"net/http"
"strings"
+ "github.com/ivinayakg/shorte.live/api/constants"
"github.com/ivinayakg/shorte.live/api/helpers"
"github.com/ivinayakg/shorte.live/api/models"
"github.com/ivinayakg/shorte.live/api/utils"
@@ -19,14 +20,26 @@ const UserAuthKey userAuth = "User"
func Authentication(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- tokenHeader := strings.Split(r.Header.Get("Authorization"), "Bearer ")
- if len(tokenHeader) < 2 {
- errMsg := "Authentication error!, Provide valid auth token"
+ var token string
+
+ cookie := utils.GetCookie(r)
+ if cookie != nil {
+ token = cookie.Value
+ } else if helpers.ENV != string(constants.Prod) {
+ tokenHeader := strings.Split(r.Header.Get("Authorization"), "Bearer ")
+ if len(tokenHeader) < 2 {
+ errMsg := "Authentication error!, Provide valid auth token"
+ helpers.SendJSONError(w, http.StatusForbidden, errMsg)
+ log.Println(errMsg)
+ return
+ }
+ token = tokenHeader[1]
+ } else {
+ errMsg := "Authentication error!, login first"
helpers.SendJSONError(w, http.StatusForbidden, errMsg)
log.Println(errMsg)
return
}
- token := tokenHeader[1]
systemNotAvailable := helpers.SystemUnderMaintenance(false)
if systemNotAvailable {
@@ -54,7 +67,9 @@ func Authentication(next http.Handler) http.Handler {
return
}
- user.Token = token
+ if helpers.ENV != string(constants.Prod) {
+ user.Token = token
+ }
c := context.WithValue(r.Context(), UserAuthKey, user)
next.ServeHTTP(w, r.WithContext(c))
diff --git a/api/sample.env b/api/sample.env
index 9bb3819..916f8b3 100644
--- a/api/sample.env
+++ b/api/sample.env
@@ -20,4 +20,5 @@ DB_CONFIG_COLLECTION_NAME="config"
SHORTED_URL_DOMAIN="localhost:5100"
FRONTEND_URL_MAINTENANCE="http://localhost:5173/maintenance"
UI_NOT_FOUND_URL="http://localhost:5173/not-found/redirect"
-ENV="development"
\ No newline at end of file
+ENV="development"
+COOKIE_NAME="shorte-cookie"
\ No newline at end of file
diff --git a/api/tests/integration/main_test.go b/api/tests/integration/main_test.go
index abd9ef1..84edb23 100644
--- a/api/tests/integration/main_test.go
+++ b/api/tests/integration/main_test.go
@@ -57,6 +57,7 @@ func setupTests() func() {
helpers.CreateDBInstance()
helpers.RedisSetup()
helpers.SetupTracker(time.Second*2, 5, 0)
+ helpers.ENV = "test"
go helpers.Tracker.StartFlush()
diff --git a/api/tests/integration/system_test.go b/api/tests/integration/system_test.go
index 23e2739..50dfc96 100644
--- a/api/tests/integration/system_test.go
+++ b/api/tests/integration/system_test.go
@@ -14,7 +14,8 @@ import (
func TestURLSystemAvailability(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, ServerURL+"/system/available", nil)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
testhelper.PutSystemUnderMaintenance(helpers.Redis, false)
@@ -22,7 +23,8 @@ func TestURLSystemAvailability(t *testing.T) {
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
body := map[string]interface{}{}
@@ -36,7 +38,8 @@ func TestURLSystemAvailability(t *testing.T) {
func TestURLSystemAvailabilityFail(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, ServerURL+"/system/available", nil)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
testhelper.PutSystemUnderMaintenance(helpers.Redis, true)
@@ -45,7 +48,8 @@ func TestURLSystemAvailabilityFail(t *testing.T) {
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
body := map[string]interface{}{}
@@ -59,7 +63,8 @@ func TestURLSystemAvailabilityFail(t *testing.T) {
func TestNotFound(t *testing.T) {
resp, err := RedirecthttpClient.Get(ServerURL + "/" + "something/random")
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
notFoundUrl := os.Getenv("UI_NOT_FOUND_URL")
@@ -71,7 +76,8 @@ func TestNotFound(t *testing.T) {
func TestRedirectHome(t *testing.T) {
resp, err := RedirecthttpClient.Get(ServerURL + "/")
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
assert.Equal(t, resp.StatusCode, http.StatusSeeOther, "Excpected status code to be 303")
diff --git a/api/tests/integration/tracking_test.go b/api/tests/integration/tracking_test.go
index edf2628..8fc33bc 100644
--- a/api/tests/integration/tracking_test.go
+++ b/api/tests/integration/tracking_test.go
@@ -16,7 +16,8 @@ import (
func TestURLRedirectTracking(t *testing.T) {
resp, err := RedirecthttpClient.Get(ServerURL + "/" + URLFixture.Short)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
destinationURL := URLFixture.Destination
@@ -29,7 +30,8 @@ func TestURLRedirectTracking(t *testing.T) {
for result == nil {
err := helpers.CurrentDb.RedirectEvent.FindOne(context.Background(), bson.M{"url_id": URLFixture.ID}).Decode(&result)
if err != nil && err != mongo.ErrNoDocuments {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
time.Sleep(time.Second * 2)
}
diff --git a/api/tests/integration/url_test.go b/api/tests/integration/url_test.go
index 3884bbf..cda75ca 100644
--- a/api/tests/integration/url_test.go
+++ b/api/tests/integration/url_test.go
@@ -20,13 +20,15 @@ var RedirecthttpClient = &http.Client{
return http.ErrUseLastResponse
},
}
+
var HttpClient = &http.Client{}
// resolve url
func TestURLResolve(t *testing.T) {
resp, err := RedirecthttpClient.Get(ServerURL + "/" + URLFixture.Short)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
destinationURL := URLFixture.Destination
@@ -38,7 +40,8 @@ func TestURLResolve(t *testing.T) {
func TestURLResolveNotFound(t *testing.T) {
resp, err := RedirecthttpClient.Get(ServerURL + "/random")
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
notFoundurl := os.Getenv("UI_NOT_FOUND_URL")
@@ -50,7 +53,8 @@ func TestURLResolveNotFound(t *testing.T) {
func TestURLResolveExpired(t *testing.T) {
resp, err := RedirecthttpClient.Get(ServerURL + "/" + ExpiredURLFixture.Short)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
notFoundurl := os.Getenv("UI_NOT_FOUND_URL")
@@ -62,14 +66,16 @@ func TestURLResolveExpired(t *testing.T) {
// test get user urls
func TestGetUserURLs(t *testing.T) {
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodGet, ServerURL+"/url/all", nil)
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := []map[string]interface{}{}
@@ -93,14 +99,16 @@ func TestCreateShortedUrl(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPost, ServerURL+"/url", bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -124,14 +132,16 @@ func TestCreateShortedUrlWithInvalidUrl(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPost, ServerURL+"/url", bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -157,14 +167,16 @@ func TestCreateShortedUrlWithInvalidUrl2(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPost, ServerURL+"/url", bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -187,14 +199,16 @@ func TestCreateShortedUrlWithPreoccupiedShort(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPost, ServerURL+"/url", bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -217,14 +231,16 @@ func TestCreateShortedUrlWithInvalidShort(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPost, ServerURL+"/url", bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -247,14 +263,16 @@ func TestCreateShortedUrlWithDuplicateShort(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPost, ServerURL+"/url", bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -276,14 +294,16 @@ func TestUpdateURL(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPatch, ServerURL+"/url/"+URLFixture.ID.Hex(), bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -306,14 +326,16 @@ func TestUpdateURLInvalidId(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPatch, ServerURL+"/url/"+primitive.NewObjectID().Hex(), bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -334,14 +356,16 @@ func TestUpdateURLUnauthorized(t *testing.T) {
payloadJSON, _ := json.Marshal(payloadData)
userJwt, _ := utils.CreateJWT(&UserFixture2)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodPatch, ServerURL+"/url/"+URLFixture.ID.Hex(), bytes.NewBuffer(payloadJSON))
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
respBody := map[string]interface{}{}
@@ -355,14 +379,16 @@ func TestUpdateURLUnauthorized(t *testing.T) {
// delete url
func TestDeleteURL(t *testing.T) {
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodDelete, ServerURL+"/url/"+ExpiredURLFixture.ID.Hex(), nil)
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
assert.Equal(t, resp.StatusCode, http.StatusNoContent, "Excpected status code to be 204")
@@ -370,14 +396,16 @@ func TestDeleteURL(t *testing.T) {
func TestDeleteURLInvalidId(t *testing.T) {
userJwt, _ := utils.CreateJWT(&UserFixture1)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodDelete, ServerURL+"/url/"+primitive.NewObjectID().Hex(), nil)
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
var respBody map[string]interface{}
@@ -389,13 +417,15 @@ func TestDeleteURLInvalidId(t *testing.T) {
func TestDeleteURLUnauthorized(t *testing.T) {
userJwt, _ := utils.CreateJWT(&UserFixture2)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, _ := http.NewRequest(http.MethodDelete, ServerURL+"/url/"+primitive.NewObjectID().Hex(), nil)
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
resp, err := HttpClient.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
var respBody map[string]interface{}
diff --git a/api/tests/integration/user_test.go b/api/tests/integration/user_test.go
index f28bc66..4f255a7 100644
--- a/api/tests/integration/user_test.go
+++ b/api/tests/integration/user_test.go
@@ -3,6 +3,7 @@ package integration_tests
import (
"context"
"encoding/json"
+ "fmt"
"net/http"
"testing"
@@ -21,7 +22,8 @@ func TestGoogleLogin(t *testing.T) {
resp, err := httpClient.Get(ServerURL + "/user/sign_in_with_google")
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
assert.Equal(t, http.StatusFound, resp.StatusCode, "Expected status code to be 302")
assert.Contains(t, resp.Header.Get("Location"), "https://accounts.google.com/o/oauth2/auth", "Expected redirect to Google OAuth URL")
@@ -33,24 +35,27 @@ func TestSelfUser(t *testing.T) {
TestDb.User.FindOne(context.Background(), bson.M{"email": "test1@gmail.com"}).Decode(&user)
userJwt, _ := utils.CreateJWT(&user)
+ authCookie := utils.CreateAuthCookie(*userJwt)
req, err := http.NewRequest(http.MethodGet, ServerURL+"/user/self", nil)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
-
- req.Header.Add("Authorization", "Bearer "+*userJwt)
+ req.AddCookie(authCookie)
// Send the request using the default HTTP client
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
body := map[string]interface{}{}
json.NewDecoder(resp.Body).Decode(&body)
+ fmt.Println(body)
assert.Equal(t, resp.StatusCode, http.StatusOK, "Expected status code to be 200")
assert.IsType(t, body["_id"], "string", "Expected _id to be a string")
@@ -60,16 +65,16 @@ func TestSelfUser(t *testing.T) {
func TestSelfUserUnauthenticated(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, ServerURL+"/user/self", nil)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
- req.Header.Add("Authorization", "Bearer hello")
-
// Send the request using the default HTTP client
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
- t.Fatal(err)
+ t.Log(err)
+ t.Fail()
}
body := map[string]interface{}{}
diff --git a/api/tests/test.env b/api/tests/test.env
index 1caecca..8a233c1 100644
--- a/api/tests/test.env
+++ b/api/tests/test.env
@@ -20,4 +20,5 @@ DB_CONFIG_COLLECTION_NAME="config"
SHORTED_URL_DOMAIN="localhost:5100"
FRONTEND_URL_MAINTENANCE="http://localhost:5173/maintenance"
UI_NOT_FOUND_URL="http://localhost:5173/not-found/redirect"
-ENV="development"
\ No newline at end of file
+ENV="development"
+COOKIE_NAME="shorte-cookie"
\ No newline at end of file
diff --git a/api/utils/jwt.go b/api/utils/jwt.go
index 9fe230a..8f3adcc 100644
--- a/api/utils/jwt.go
+++ b/api/utils/jwt.go
@@ -2,6 +2,7 @@ package utils
import (
"fmt"
+ "net/http"
"os"
"strconv"
"time"
@@ -62,3 +63,44 @@ func VerifyJwt(tokenString string) (*map[string]string, error) {
return nil, fmt.Errorf("failed to extract claims from token")
}
}
+
+func CreateAuthCookie(token string) *http.Cookie {
+ cookieName := os.Getenv("COOKIE_NAME")
+ var expiry = os.Getenv("JWT_EXPIRY")
+ expiryTotal, err := strconv.Atoi(expiry)
+ if err != nil {
+ fmt.Println("Error:", err)
+ expiryTotal = 21600
+ }
+
+ return &http.Cookie{
+ Name: cookieName,
+ Value: token,
+ MaxAge: expiryTotal,
+ HttpOnly: true,
+ Secure: true,
+ SameSite: http.SameSiteLaxMode,
+ Path: "/",
+ }
+}
+
+func RemoveAuthCookie() *http.Cookie {
+ cookieName := os.Getenv("COOKIE_NAME")
+ return &http.Cookie{
+ Name: cookieName,
+ Value: "",
+ Expires: time.Now().Add(-time.Hour),
+ HttpOnly: true,
+ Secure: true,
+ SameSite: http.SameSiteLaxMode,
+ }
+}
+
+func GetCookie(r *http.Request) *http.Cookie {
+ cookieName := os.Getenv("COOKIE_NAME")
+ cookie, err := r.Cookie(cookieName)
+ if err != nil {
+ return nil
+ }
+ return cookie
+}
diff --git a/client/src/App.tsx b/client/src/App.tsx
index dea8966..357716d 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -3,7 +3,7 @@ import "./App.css";
import { createBrowserRouter, Outlet, RouterProvider } from "react-router-dom";
import { MainProvider } from "@/components/main-provider";
import { Toaster } from "@/components/ui/toaster";
-import { AuthComponent } from "@/utils/auth";
+// import { AuthComponent } from "@/utils/auth";
import MyUrls from "@/pages/MyUrls";
import Header from "@/components/Header";
import CreateShort from "@/pages/CreateShort";
@@ -33,10 +33,10 @@ const router = createBrowserRouter([
},
],
},
- {
- path: "/auth/",
- element: ,
- },
+ // {
+ // path: "/auth/",
+ // element: ,
+ // },
]);
function Main() {
diff --git a/client/src/components/DeleteURLModal.tsx b/client/src/components/DeleteURLModal.tsx
index 19aeaee..b7f2ceb 100644
--- a/client/src/components/DeleteURLModal.tsx
+++ b/client/src/components/DeleteURLModal.tsx
@@ -30,7 +30,7 @@ function DeleteURL(
const { toast } = useToast();
const deleteURLForm = async () => {
const res = await fetch.delete(`/url/${urlObj._id}`, {
- headers: { Authorization: `Bearer ${userState.token}` },
+ withCredentials: true,
});
if (res.status === 204) {
toast({
diff --git a/client/src/components/UpdateURLModal.tsx b/client/src/components/UpdateURLModal.tsx
index 903ee4f..d49cfd1 100644
--- a/client/src/components/UpdateURLModal.tsx
+++ b/client/src/components/UpdateURLModal.tsx
@@ -55,7 +55,7 @@ function UpdateURL(
}
const res = await fetch.patch(`/url/${urlObj._id}`, request, {
- headers: { Authorization: `Bearer ${userState.token}` },
+ withCredentials: true,
});
if (res.status === 204) {
toast({
diff --git a/client/src/components/main-provider.tsx b/client/src/components/main-provider.tsx
index 1968d91..637b003 100644
--- a/client/src/components/main-provider.tsx
+++ b/client/src/components/main-provider.tsx
@@ -1,8 +1,7 @@
-import auth from "@/utils/auth";
-import { getFromLocalStorage } from "@/utils/localstorage";
import { createContext, useContext, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useToast } from "@/components/ui/use-toast";
+import fetch from "@/utils/axios";
export type UserState = {
email: string;
@@ -10,7 +9,6 @@ export type UserState = {
picture: string;
_id: string;
created_at: string;
- token: string;
login: boolean;
};
@@ -29,7 +27,6 @@ const initialUserState: UserState = {
picture: "",
_id: "",
created_at: "",
- token: "",
login: false,
};
@@ -52,22 +49,18 @@ export function MainProvider({ children, ...props }: MainProviderProps) {
useEffect(() => {
(async () => {
try {
- const token = getFromLocalStorage("userToken");
- if (token) {
- const response = await auth(token);
- if (response?.status !== 200) {
- resetState(setUserState);
- navigate("/");
- } else {
- setUserState({ ...response.data, login: true });
- toast({
- title: "Logged in Successfully",
- duration: 2000,
- });
- }
- } else {
+ const response = await fetch.get("/user/self", {
+ withCredentials: true,
+ });
+ if (response?.status !== 200) {
resetState(setUserState);
navigate("/");
+ } else {
+ setUserState({ ...response.data, login: true });
+ toast({
+ title: "Logged in Successfully",
+ duration: 2000,
+ });
}
} catch (e: any) {
if (typeof e === "string") toast({ title: e, duration: 2000 });
diff --git a/client/src/pages/CreateShort.tsx b/client/src/pages/CreateShort.tsx
index 6580cc1..73dbb13 100644
--- a/client/src/pages/CreateShort.tsx
+++ b/client/src/pages/CreateShort.tsx
@@ -35,7 +35,7 @@ function CreateShort() {
};
const res = await fetch.post("/url", requestData, {
- headers: { Authorization: `Bearer ${userState.token}` },
+ withCredentials: true,
});
if (res.status !== 201) {
throw new Error("Check again later");
diff --git a/client/src/pages/MyUrls.tsx b/client/src/pages/MyUrls.tsx
index 5a201e2..a6dfb07 100644
--- a/client/src/pages/MyUrls.tsx
+++ b/client/src/pages/MyUrls.tsx
@@ -21,7 +21,7 @@ function MyUrls() {
if (userState.login && location.pathname === "/my-urls") {
(async () => {
const res = await fetch.get("/url/all", {
- headers: { Authorization: `Bearer ${userState.token}` },
+ withCredentials: true,
});
const data = res.data;
setUrlsData(data);
diff --git a/client/src/utils/auth.tsx b/client/src/utils/auth.tsx
index 53d4270..f228efc 100644
--- a/client/src/utils/auth.tsx
+++ b/client/src/utils/auth.tsx
@@ -1,21 +1,7 @@
import { useNavigate, useSearchParams } from "react-router-dom";
-import fetch from "./axios";
import { setInLocalStorage } from "./localstorage";
import { useEffect } from "react";
-export default async function (token: string) {
- if (!token) return;
- const res = await fetch.get("/user/self", {
- headers: { Authorization: `Bearer ${token}` },
- });
- if (res.status !== 200) {
- setInLocalStorage("userToken", null);
- } else {
- setInLocalStorage("userToken", token);
- }
- return res;
-}
-
function AuthComponent() {
const [searchParams] = useSearchParams();
const navigate = useNavigate();