diff --git a/.gitignore b/.gitignore index 8268837..00d78db 100644 --- a/.gitignore +++ b/.gitignore @@ -43,5 +43,5 @@ app.*.map.json /android/app/profile /android/app/release -/server/constant/const.go +/server/.env /lib/global/baseurl.dart diff --git a/lib/global/color.dart b/lib/global/color.dart index de4b56e..fbc3984 100644 --- a/lib/global/color.dart +++ b/lib/global/color.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; const Color klightBlue = Color(0xFFEAF7FF); const Color kdarkBlue = Color(0xFF488BB7); -const Color kdarkBlueMuted = Color(0xFF5495C2); +Color kdarkBlueMuted = Color(0xFF5495C2).withOpacity(0.7); const Color kpurple = Color(0xFF9B7CF5); const Color klightPurple = Color(0xFF9797D3); const Color kyellow = Color(0xFFF2C634); diff --git a/lib/main.dart b/lib/main.dart index 350bf77..238b05c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -47,7 +47,7 @@ class MyApp extends StatelessWidget { // Camera.routeName: (context) => Camera(), // SpecificNeeds.routeName: (context) => SpecificNeeds(), }, - home: NavScreen(), + home: WelcomeScreen(), ); } } diff --git a/lib/screens/auth/auth_screen.dart b/lib/screens/auth/auth_screen.dart index 6367dae..959fc78 100644 --- a/lib/screens/auth/auth_screen.dart +++ b/lib/screens/auth/auth_screen.dart @@ -175,30 +175,30 @@ class _AuthScreenState extends State with TickerProviderStateMixin { ], ), ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: GestureDetector( - onTap: () {}, - child: Container( - width: double.infinity, - height: 50, - decoration: BoxDecoration( - border: Border.all(color: Colors.black), - borderRadius: BorderRadius.circular(16), - color: Colors.white, - ), - child: const Center( - child: Text( - "Log In with Google", - style: TextStyle(), - ), - ), - ), - ), - ), - const SizedBox( - height: 40, - ), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 24), + // child: GestureDetector( + // onTap: () {}, + // child: Container( + // width: double.infinity, + // height: 50, + // decoration: BoxDecoration( + // border: Border.all(color: Colors.black), + // borderRadius: BorderRadius.circular(16), + // color: Colors.white, + // ), + // child: const Center( + // child: Text( + // "Log In with Google", + // style: TextStyle(), + // ), + // ), + // ), + // ), + // ), + // const SizedBox( + // height: 40, + // ), ], ), ); diff --git a/lib/screens/auth/signup_screen.dart b/lib/screens/auth/signup_screen.dart index 89184b4..291b814 100644 --- a/lib/screens/auth/signup_screen.dart +++ b/lib/screens/auth/signup_screen.dart @@ -44,6 +44,7 @@ class Signup extends StatelessWidget { const Spacer(flex: 2), GestureDetector( onTap: () { + Navigator.pushNamed(context, '/tabScreen'); AuthServices().postSignUp( name: nameController.text, email: emailController.text, diff --git a/lib/screens/home/components/mediatation_card.dart b/lib/screens/home/components/mediatation_card.dart index 304e003..8bb9cae 100644 --- a/lib/screens/home/components/mediatation_card.dart +++ b/lib/screens/home/components/mediatation_card.dart @@ -25,7 +25,7 @@ class _MeditationState extends State { double height = MediaQuery.of(context).size.height; double width = MediaQuery.of(context).size.width; return SizedBox( - height: height * 0.25, + height: height * 0.24, child: PageView.builder( clipBehavior: Clip.none, controller: pageController, @@ -48,8 +48,7 @@ class _MeditationState extends State { children: [ Container( clipBehavior: Clip.none, - margin: - const EdgeInsets.only(left: 8, right: 8, bottom: 24), + margin: const EdgeInsets.only(left: 8, right: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), @@ -73,7 +72,7 @@ class _MeditationState extends State { ), ), Positioned( - bottom: 60, + bottom: height * 0.052, left: 30, child: Text( "Meditation ${index + 1}", diff --git a/lib/screens/home/components/yoga_card.dart b/lib/screens/home/components/yoga_card.dart new file mode 100644 index 0000000..cf87873 --- /dev/null +++ b/lib/screens/home/components/yoga_card.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +class YogaCard extends StatelessWidget { + const YogaCard({super.key}); + + @override + Widget build(BuildContext context) { + double height = MediaQuery.of(context).size.height; + double width = MediaQuery.of(context).size.width; + return ListView.builder( + scrollDirection: Axis.vertical, + itemCount: 3, + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.only(bottom: 16, left: 24, right: 24), + child: Container( + width: width * 0.8, + height: 80, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.03), + offset: const Offset(8, 20), + blurRadius: 24, + ), + ], + ), + ), + ); + }); + } +} diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index c6aed47..af109c5 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -3,6 +3,8 @@ import 'package:yogzen/global/color.dart'; import 'package:yogzen/screens/home/components/mediatation_card.dart'; import 'dart:math' as math; +import 'package:yogzen/screens/home/components/yoga_card.dart'; + class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @@ -51,13 +53,14 @@ class _HomeScreenState extends State { height: height * 0.3, width: width, decoration: BoxDecoration( - image: DecorationImage( - opacity: 0.3, - image: Image.asset( - "assets/mountain.jpeg", - ).image, - fit: BoxFit.cover, - ), + // image: DecorationImage( + // opacity: 0.3, + // image: Image.asset( + // "assets/mountain.jpeg", + // ).image, + // fit: BoxFit.cover, + // ), + color: kdarkBlue, ), child: Column( @@ -111,10 +114,9 @@ class _HomeScreenState extends State { clipBehavior: Clip.none, children: [ Container( - height: height * 0.12, width: width * 0.8, - decoration: const BoxDecoration( + decoration: BoxDecoration( color: kdarkBlueMuted, borderRadius: BorderRadius.only( topRight: Radius.circular(100), @@ -180,12 +182,18 @@ class _HomeScreenState extends State { // meditation Padding( - padding: const EdgeInsets.only(left: 16, top: 24, bottom: 22), + padding: const EdgeInsets.only(left: 16, top: 24, bottom: 20), child: Text("Meditation", style: Theme.of(context).textTheme.headlineMedium), ), const Meditation(), + Padding( + padding: const EdgeInsets.only(left: 16, bottom: 0), + child: Text("Yoga Library", + style: Theme.of(context).textTheme.headlineMedium), + ), + const YogaCard(), ], ), ), diff --git a/lib/screens/welcome/welcome_screen.dart b/lib/screens/welcome/welcome_screen.dart index 2aad6ec..f0b20f8 100644 --- a/lib/screens/welcome/welcome_screen.dart +++ b/lib/screens/welcome/welcome_screen.dart @@ -49,58 +49,82 @@ class _WelcomeScreenState extends State Widget build(BuildContext context) { return Scaffold( backgroundColor: klightBlue, - body: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Spacer(), - Text( - 'Yogzen', - style: TextStyle( - color: kblackHeading, - fontSize: 32, - fontWeight: FontWeight.w600), - ), - const SizedBox( - height: 30, - ), - Text( - 'AI enabled yoga app for all your ', - style: TextStyle(color: kblackSubHeading), - ), - Text( - 'yogic needs!', - style: TextStyle(color: kblackSubHeading), - ), - Spacer(), - AnimatedContainer( + body: Container( + decoration: BoxDecoration( + color: Colors.white, + image: DecorationImage( + opacity: 0.7, + image: Image.asset( + 'assets/meditation/img2.jpeg', + ).image, + fit: BoxFit.cover), + ), + child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Spacer(), + Text( + 'Yogzen', + style: TextStyle( + color: kblackHeading, + fontSize: 32, + fontWeight: FontWeight.w600), + ), + const SizedBox( + height: 30, + ), + Text( + 'AI enabled yoga app for all your ', + style: TextStyle(color: kblackSubHeading), + ), + Text( + 'yogic needs!', + style: TextStyle(color: kblackSubHeading), + ), + Spacer(), + AnimatedContainer( duration: Duration(milliseconds: 1500), transform: Transform.translate( offset: Offset(0, animation!.value), ).transform, child: Hero( - tag: "welcome", - child: Image.asset('assets/welcome.png'))), - Spacer(), - ElevatedButton( - onPressed: () { - Navigator.pushNamed(context, "/auth"); - }, - style: ElevatedButton.styleFrom( - backgroundColor: kdarkBlue, - foregroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(100))), - child: const Padding( - padding: EdgeInsets.fromLTRB(50, 14, 50, 14), - child: Text('Get Started', style: TextStyle(fontSize: 16)), + tag: "welcome", + child: Container( + child: Image.asset('assets/welcome.png'), + decoration: BoxDecoration( + // boxShadow: [ + // BoxShadow( + // color: Colors.black.withOpacity(0.1), + // offset: const Offset(8, 20), + // blurRadius: 24, + // ), + // ], + ), + ), + ), + ), + Spacer(), + ElevatedButton( + onPressed: () { + Navigator.pushNamed(context, "/auth"); + }, + style: ElevatedButton.styleFrom( + backgroundColor: kdarkBlue, + foregroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100))), + child: const Padding( + padding: EdgeInsets.fromLTRB(50, 14, 50, 14), + child: Text('Get Started', style: TextStyle(fontSize: 16)), + ), + ), + const SizedBox( + height: 50, ), - ), - const SizedBox( - height: 50, - ), - ], - ) - ])); + ], + ) + ]), + )); } } diff --git a/server/constant/const.go b/server/constant/const.go new file mode 100644 index 0000000..4730205 --- /dev/null +++ b/server/constant/const.go @@ -0,0 +1,7 @@ +package constant + + + +const DbName = "Yogzen" +const ColName = "Users" + diff --git a/server/controller/controller.go b/server/controller/controller.go index 73d49fb..e16bbdc 100644 --- a/server/controller/controller.go +++ b/server/controller/controller.go @@ -1,165 +1,165 @@ package controller -import ( - "context" - "encoding/json" - "fmt" - "github/Yash-Khattar/yogzen-server/constant" - "github/Yash-Khattar/yogzen-server/model" - "log" - "net/http" - "time" - - "github.com/golang-jwt/jwt" - "github.com/gorilla/mux" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "golang.org/x/crypto/bcrypt" -) - -var collection *mongo.Collection - -func init() { - clientOption := options.Client().ApplyURI(constant.Mongodbkey) - client, err := mongo.Connect(context.TODO(), clientOption) - if err != nil { - log.Fatal(err) - } - - fmt.Println("MongoDB connected successfully") - collection = client.Database(constant.DbName).Collection(constant.ColName) -} - -// func error(err error ){ -// log.Fatal(err) +// import ( +// "context" +// "encoding/json" +// "fmt" +// "github/Yash-Khattar/yogzen-server/constant" +// "github/Yash-Khattar/yogzen-server/model" +// "log" +// "net/http" +// "time" + +// "github.com/golang-jwt/jwt" +// "github.com/gorilla/mux" +// "go.mongodb.org/mongo-driver/bson" +// "go.mongodb.org/mongo-driver/mongo" +// "go.mongodb.org/mongo-driver/mongo/options" +// "golang.org/x/crypto/bcrypt" +// ) + +// var collection *mongo.Collection + +// func init() { +// clientOption := options.Client().ApplyURI(constant.Mongodbkey) +// client, err := mongo.Connect(context.TODO(), clientOption) +// if err != nil { +// log.Fatal(err) +// } + +// fmt.Println("MongoDB connected successfully") +// collection = client.Database(constant.DbName).Collection(constant.ColName) // } -//APIS - -//Authentication - -// signup -func SignUp(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - var user model.UserModel - json.NewDecoder(r.Body).Decode(&user) - password := []byte(user.Password) - filter := bson.M{"email": user.Email} - var result bson.M - err := collection.FindOne(context.Background(), filter).Decode(&result) - - if err != nil { - // no doc found => signup - if err == mongo.ErrNoDocuments { - json.NewEncoder(w).Encode("no document found") - hashedPassword, err := bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost) - if err != nil { - log.Fatal(err) - } - user.Password = string(hashedPassword) - inserted, _ := collection.InsertOne(context.Background(), user) - json.NewEncoder(w).Encode(inserted) - return - } - log.Fatal(err) - } - //login api call - w.WriteHeader(http.StatusBadRequest) - json.NewEncoder(w).Encode("document found : login instead") - fmt.Printf("found document %v", result) -} - -// signin -func SignIn(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - var user model.UserModel - // email and password - json.NewDecoder(r.Body).Decode(&user) - password := []byte(user.Password) - filter := bson.M{"email": user.Email} - var result bson.M - err := collection.FindOne(context.Background(), filter).Decode(&result) - if err != nil { - if err == mongo.ErrNoDocuments { - // user does not exists => sign up - w.WriteHeader(http.StatusBadRequest) - json.NewEncoder(w).Encode("user does not exist, signup instead") - return - } - log.Fatal(err) - } - //user exists - //match password - bsonBytes, _ := bson.Marshal(result) - bson.Unmarshal(bsonBytes, &user) - - err = bcrypt.CompareHashAndPassword([]byte(user.Password), password) - // nil means it is a match - if err != nil { - w.WriteHeader(http.StatusBadRequest) - json.NewEncoder(w).Encode("wrong password") - return - } - //jwt token - token, err := createToken(user.ID.Hex()) - json.NewEncoder(w).Encode(token) - -} - -// create jwt token - -func createToken(id string) (string, error) { - token := jwt.NewWithClaims(jwt.SigningMethodHS256, - jwt.MapClaims{ - "id": id, - "exp": time.Now().Add(time.Hour * 24).Unix(), - }) - - tokenString, err := token.SignedString(constant.SecretKey) - if err != nil { - return "", err - } - - return tokenString, nil -} - -// verify token -func VerifyToken(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - params := mux.Vars(r) - - // if token is empty - if params["token"] == "" { - json.NewEncoder(w).Encode(false) - } - - // if token is valid - err := verifyJWTToken(params["token"]) - if err != nil { - json.NewEncoder(w).Encode(false) - return - } - - // if user is empty - - json.NewEncoder(w).Encode(true) - -} - -// jwt verify -func verifyJWTToken(tokenString string) error { - token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { - return constant.SecretKey, nil - }) - - if err != nil { - return err - } - - if !token.Valid { - return fmt.Errorf("invalid token") - } - - return nil -} +// // func error(err error ){ +// // log.Fatal(err) +// // } + +// //APIS + +// //Authentication + +// // signup +// func SignUp(w http.ResponseWriter, r *http.Request) { +// w.Header().Set("Content-Type", "application/json") +// var user model.User +// json.NewDecoder(r.Body).Decode(&user) +// password := []byte(user.Password) +// filter := bson.M{"email": user.Email} +// var result bson.M +// err := collection.FindOne(context.Background(), filter).Decode(&result) + +// if err != nil { +// // no doc found => signup +// if err == mongo.ErrNoDocuments { +// json.NewEncoder(w).Encode("no document found") +// hashedPassword, err := bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost) +// if err != nil { +// log.Fatal(err) +// } +// user.Password = string(hashedPassword) +// inserted, _ := collection.InsertOne(context.Background(), user) +// json.NewEncoder(w).Encode(inserted) +// return +// } +// log.Fatal(err) +// } +// //login api call +// w.WriteHeader(http.StatusBadRequest) +// json.NewEncoder(w).Encode("document found : login instead") +// fmt.Printf("found document %v", result) +// } + +// // signin +// func SignIn(w http.ResponseWriter, r *http.Request) { +// w.Header().Set("Content-Type", "application/json") +// var user model.User +// // email and password +// json.NewDecoder(r.Body).Decode(&user) +// password := []byte(user.Password) +// filter := bson.M{"email": user.Email} +// var result bson.M +// err := collection.FindOne(context.Background(), filter).Decode(&result) +// if err != nil { +// if err == mongo.ErrNoDocuments { +// // user does not exists => sign up +// w.WriteHeader(http.StatusBadRequest) +// json.NewEncoder(w).Encode("user does not exist, signup instead") +// return +// } +// log.Fatal(err) +// } +// //user exists +// //match password +// bsonBytes, _ := bson.Marshal(result) +// bson.Unmarshal(bsonBytes, &user) + +// err = bcrypt.CompareHashAndPassword([]byte(user.Password), password) +// // nil means it is a match +// if err != nil { +// w.WriteHeader(http.StatusBadRequest) +// json.NewEncoder(w).Encode("wrong password") +// return +// } +// //jwt token +// token, err := createToken(user.ID.Hex()) +// json.NewEncoder(w).Encode(token) + +// } + +// // create jwt token + +// func createToken(id string) (string, error) { +// token := jwt.NewWithClaims(jwt.SigningMethodHS256, +// jwt.MapClaims{ +// "id": id, +// "exp": time.Now().Add(time.Hour * 24).Unix(), +// }) + +// tokenString, err := token.SignedString(constant.SecretKey) +// if err != nil { +// return "", err +// } + +// return tokenString, nil +// } + +// // verify token +// func VerifyToken(w http.ResponseWriter, r *http.Request) { +// w.Header().Set("Content-Type", "application/json") +// params := mux.Vars(r) + +// // if token is empty +// if params["token"] == "" { +// json.NewEncoder(w).Encode(false) +// } + +// // if token is valid +// err := verifyJWTToken(params["token"]) +// if err != nil { +// json.NewEncoder(w).Encode(false) +// return +// } + +// // if user is empty + +// json.NewEncoder(w).Encode(true) + +// } + +// // jwt verify +// func verifyJWTToken(tokenString string) error { +// token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { +// return constant.SecretKey, nil +// }) + +// if err != nil { +// return err +// } + +// if !token.Valid { +// return fmt.Errorf("invalid token") +// } + +// return nil +// } diff --git a/server/controller/userController.go b/server/controller/userController.go new file mode 100644 index 0000000..9aa4e4d --- /dev/null +++ b/server/controller/userController.go @@ -0,0 +1,195 @@ +package controller + +import ( + "context" + "fmt" + "github/Yash-Khattar/yogzen-server/database" + "github/Yash-Khattar/yogzen-server/helper" + "github/Yash-Khattar/yogzen-server/model" + "log" + "net/http" + + "time" + + "github.com/gin-gonic/gin" + "github.com/go-playground/validator/v10" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo" + "golang.org/x/crypto/bcrypt" +) + +var userCollection *mongo.Collection = database.OpenCollection(database.Client, "user") +var validate = validator.New() + +func HashPassword(password string) string { + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), 14) + if err != nil { + log.Panic(err) + } + return string(hashedPassword) +} + +func VerifyPassword(userPassword string, providedPassword string) (bool, string) { + err := bcrypt.CompareHashAndPassword([]byte(providedPassword), []byte(userPassword)) + check := true + msg := "" + + if err != nil { + msg = fmt.Sprintf("email of password is incorrect") + check = false + } + return check, msg +} + +func Signup() gin.HandlerFunc { + return func(c *gin.Context) { + var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) + defer cancel() + var user model.User + + if err := c.BindJSON(&user); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + validationErr := validate.Struct(user) + if validationErr != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": validationErr.Error()}) + return + } + + count, err := userCollection.CountDocuments(ctx, bson.M{"email": user.Email}) + defer cancel() + if err != nil { + log.Panic(err) + c.JSON(http.StatusInternalServerError, gin.H{"error": "error while checking email"}) + return + } + password := HashPassword(*user.Password) + user.Password = &password + if count > 0 { + c.JSON(http.StatusInternalServerError, gin.H{"error": "user alraedy exists"}) + } + + user.CreatedAt, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) + user.UpdatedAt, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) + user.ID = primitive.NewObjectID() + user.UserId = user.ID.Hex() + token, refreshToken, err := helper.GenerateAllToken(*user.Email, *user.Name, *user.UserType, *&user.UserId) + if err != nil { + log.Panic(err) + c.JSON(http.StatusInternalServerError, gin.H{"error": "token error"}) + return + } + user.Token = &token + user.RefreshToken = &refreshToken + + resultInsertedNumber, insertErr := userCollection.InsertOne(ctx, user) + if insertErr != nil { + msg := fmt.Sprint("User item was not created") + c.JSON(http.StatusInternalServerError, gin.H{"error": msg}) + return + } + c.JSON(http.StatusOK, resultInsertedNumber) + + } +} + +func Login() gin.HandlerFunc { + return func(c *gin.Context) { + var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) + defer cancel() + var user model.User + var foundUser model.User + if err := c.BindJSON(&user); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + err := userCollection.FindOne(ctx, bson.M{"email": user.Email}).Decode(&foundUser) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "email or password is incorrect"}) + return + } + + passwordIsValid, msg := VerifyPassword(*user.Password, *foundUser.Password) + if passwordIsValid != true { + c.JSON(http.StatusInternalServerError, gin.H{"error": msg}) + return + } + if foundUser.Email == nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "user not found"}) + } + token, refreshToken, err := helper.GenerateAllToken(*foundUser.Email, *foundUser.Name, *foundUser.UserType, *&foundUser.UserId) + if err != nil { + log.Panic(err) + c.JSON(http.StatusInternalServerError, gin.H{"error": "token error"}) + return + } + helper.UpdateAllToken(token, refreshToken, foundUser.UserId) + err = userCollection.FindOne(ctx, bson.M{"user_id": foundUser.UserId}).Decode(&foundUser) + + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusOK, foundUser) + + } +} + +func GetUser() gin.HandlerFunc { + return func(c *gin.Context) { + userId := c.Param("user_id") + + if err := helper.MachUserTypeToUid(c, userId); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) + + var user model.User + err := userCollection.FindOne(ctx, bson.M{"user_id": userId}).Decode(&user) + defer cancel() + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + c.JSON(http.StatusOK, user) + + } +} + +// func GetUsers() gin.HandlerFunc { +// return func(c *gin.Context) { +// err := helper.CheckUserType(c, "ADMIN") +// if err != nil { +// c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) +// return +// } +// var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) +// defer cancel() +// recordPerPage, err := strconv.Atoi(c.Query("recordPerPage")) +// if err != nil || recordPerPage < 1 { +// recordPerPage = 10 +// } +// page, err1 := strconv.Atoi(c.Query("page")) +// if err1 != nil || page < 1 { +// page = 1 +// } +// startIndex := (page -1)* recordPerPage +// startIndex, err = strconv.Atoi(c.Query("startIndex")) +// matchStage := bson.D{{"$match", bson.D{{}}} + +// groupStage := bson.D{{"$group", bson.D{{"_id", bson.D{{"_id", "null"}}},{"total_count", bson.D{{"$sum", 1}}}, {"data", bson.D{{"$push", "$root"}}},}}} +// projectStage := bson.D{ +// { +// "$project", bson.D{ +// {"_id", 0}, {"total_count". 1}, +// {"user_items", bson.D{{"$slice", []interface{}{"$data", startIndex, recordPerPage}}}} +// }, +// } +// } + +// }} +// } diff --git a/server/database/databaseConnection.go b/server/database/databaseConnection.go new file mode 100644 index 0000000..65a2c61 --- /dev/null +++ b/server/database/databaseConnection.go @@ -0,0 +1,48 @@ +package database + +import ( + "context" + "fmt" + "github/Yash-Khattar/yogzen-server/constant" + "log" + "os" + "time" + + "github.com/joho/godotenv" + + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + + + + +func DBinstance() *mongo.Client { + err := godotenv.Load(".env") + if err != nil { + log.Fatal("error loading env file") + } + + MongoDb := os.Getenv("MONGODB_URL") + clientOption := options.Client().ApplyURI(MongoDb) + + +ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) +defer cancel() +client, err := mongo.Connect(ctx, clientOption) + if err != nil { + log.Fatal(err) + } + + fmt.Println("MongoDB connected successfully") + return client + +} + +var Client *mongo.Client = DBinstance() + +func OpenCollection(client *mongo.Client, collectionName string) *mongo.Collection{ +var collection *mongo.Collection = client.Database(constant.DbName).Collection(collectionName) +return collection +} + diff --git a/server/go.mod b/server/go.mod index 9b94845..920ed28 100644 --- a/server/go.mod +++ b/server/go.mod @@ -2,20 +2,47 @@ module github/Yash-Khattar/yogzen-server go 1.21.2 -require github.com/gorilla/mux v1.8.1 +require ( + github.com/gin-gonic/gin v1.9.1 + github.com/go-playground/validator/v10 v10.14.0 +) + +require ( + github.com/bytedance/sonic v1.9.1 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + golang.org/x/arch v0.3.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) require ( github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/golang-jwt/jwt/v5 v5.1.0 // indirect github.com/golang/snappy v0.0.1 // indirect + github.com/joho/godotenv v1.5.1 github.com/klauspost/compress v1.13.6 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect - go.mongodb.org/mongo-driver v1.13.0 // indirect - golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect + go.mongodb.org/mongo-driver v1.13.0 + golang.org/x/crypto v0.9.0 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect ) diff --git a/server/go.sum b/server/go.sum index 0ee3ead..648609f 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,17 +1,76 @@ +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v5 v5.1.0 h1:UGKbA/IPjtS6zLcdB7i5TyACMgSbOTiR8qzXgw8HWQU= -github.com/golang-jwt/jwt/v5 v5.1.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= @@ -23,15 +82,21 @@ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7Jul github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.mongodb.org/mongo-driver v1.13.0 h1:67DgFFjYOCMWdtTEmKFpV3ffWlFnh+CYZ8ZS/tXWUfY= go.mongodb.org/mongo-driver v1.13.0/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -40,7 +105,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -48,10 +117,21 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/server/helper/authHelper.go b/server/helper/authHelper.go new file mode 100644 index 0000000..92222fb --- /dev/null +++ b/server/helper/authHelper.go @@ -0,0 +1,32 @@ +package helper + +import ( + "errors" + + "github.com/gin-gonic/gin" + +) + +func CheckUserType(c *gin.Context, role string) (err error){ + userType := c.GetString("user_type") + err = nil + if userType != role { + err = errors.New("Unauthorized to access this resource") + return err + } + return err +} + +func MachUserTypeToUid(c *gin.Context, userId string) (err error){ + userType := c.GetString("user_type") + uid := c.GetString("uid") + err = nil + if userType == "USER" && uid != userId { + err = errors.New("Unauthorized to access this resource") + return err + } + +err = CheckUserType(c, userType) +return err +} + diff --git a/server/helper/tokenHelper.go b/server/helper/tokenHelper.go new file mode 100644 index 0000000..8e3985b --- /dev/null +++ b/server/helper/tokenHelper.go @@ -0,0 +1,103 @@ +package helper + +import ( + "context" + "fmt" + "github/Yash-Khattar/yogzen-server/database" + "log" + "os" + "time" + + "github.com/golang-jwt/jwt" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type SignedDetails struct { + Email string + Name string + Uid string + User_type string + jwt.StandardClaims +} + +var userCollection *mongo.Collection = database.OpenCollection(database.Client, "user") + +var SECRET_KEY string = os.Getenv("SECRECT_KEY") + +func GenerateAllToken(email string, name string, userType string, uid string) (signedToken string, signedRefreshToken string, err error) { + claims := &SignedDetails{ + Email: email, + Name: name, + Uid: uid, + User_type: userType, + StandardClaims: jwt.StandardClaims{ + ExpiresAt: time.Now().Local().Add(time.Hour * time.Duration(168)).Unix(), + }, + } + refreshClaims := &SignedDetails{ + StandardClaims: jwt.StandardClaims{ + ExpiresAt: time.Now().Local().Add(time.Hour * time.Duration(168)).Unix(), + }, + } + token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(SECRET_KEY)) + refreshToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims).SignedString([]byte(SECRET_KEY)) + if err != nil { + log.Panic(err) + return + } + return token, refreshToken, err +} +func UpdateAllToken(signedToken string, signedRefreshToken string, userId string) { + var ctx, cancel = context.WithTimeout(context.Background(), 100*time.Second) + defer cancel() + var updateObj primitive.D + + updateObj = append(updateObj, bson.E{"token", signedToken}) + updateObj = append(updateObj, bson.E{"refresh_token", signedRefreshToken}) + Updated_at, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) + updateObj = append(updateObj, bson.E{"updated_at", Updated_at}) + + upsert := true + filter := bson.M{"user_id": userId} + opt := options.UpdateOptions{ + Upsert: &upsert, + } + + _, err := userCollection.UpdateOne(ctx, filter, bson.D{ + {"$set", updateObj}, + }, &opt) + if err != nil { + log.Panic(err) + return + } + return + +} + +func ValidateToken(signedToken string) (claims *SignedDetails, msg string) { + token, err := jwt.ParseWithClaims( + signedToken, &SignedDetails{}, + func(token *jwt.Token) (interface{}, error) { + return []byte(SECRET_KEY), nil + }, + ) + if err != nil { + msg = err.Error() + return + } + claims, ok := token.Claims.(*SignedDetails) + if !ok { + msg = fmt.Sprintf("the token is invalid") + msg = err.Error() + return + } + if claims.ExpiresAt < time.Now().Local().Unix() { + msg = fmt.Sprintf("token is expired") + msg = err.Error() + return + } + return claims, msg +} diff --git a/server/main.go b/server/main.go index 5a3c86b..15171b6 100644 --- a/server/main.go +++ b/server/main.go @@ -2,14 +2,32 @@ package main import ( "fmt" - "github/Yash-Khattar/yogzen-server/router" - "log" - "net/http" + // "github/Yash-Khattar/yogzen-server/router" + + routes "github/Yash-Khattar/yogzen-server/routes" + "os" + + "github.com/gin-gonic/gin" ) func main() { fmt.Println("Welcome to Yogzen") - r := router.Router() - log.Fatal(http.ListenAndServe(":3000", r)) - fmt.Println("connection success") + // r := router.Router() + // log.Fatal(http.ListenAndServe(":3000", r)) + // fmt.Println("connection success") + port := os.Getenv("PORT") + if port == "" { + port = "3000" + } + router := gin.New() + router.Use(gin.Logger()) + + router.GET("/", func(c *gin.Context) { + c.JSON(200, gin.H{ + "message": "Welcome to Yogzen", + }) + }) + routes.AuthRouter(router) + routes.UserRoutes(router) + router.Run(":" + port) } diff --git a/server/middleware/authMiddleware.go b/server/middleware/authMiddleware.go new file mode 100644 index 0000000..c1ece1a --- /dev/null +++ b/server/middleware/authMiddleware.go @@ -0,0 +1,33 @@ +package middleware + +import ( + helper "github/Yash-Khattar/yogzen-server/helper" + "net/http" + + "github.com/gin-gonic/gin" +) + +func Authenticate() gin.HandlerFunc { + return func(c *gin.Context) { + clientToken := c.Request.Header.Get("token") + if clientToken == "" { + c.JSON(http.StatusInternalServerError, gin.H{"error": "no authrization headers provided"}) + + c.Abort() + return + } + + claims, err := helper.ValidateToken(clientToken) + if err != "" { + c.JSON(http.StatusInternalServerError, gin.H{"error": err}) + c.Abort() + return + + } + c.Set("email", claims.Email) + c.Set("name", claims.Name) + c.Set("uid", claims.Uid) + c.Set("user_type", claims.User_type) + c.Next() + } +} diff --git a/server/model/user_model.go b/server/model/user_model.go index 32090c6..663b052 100644 --- a/server/model/user_model.go +++ b/server/model/user_model.go @@ -1,11 +1,21 @@ package model -import "go.mongodb.org/mongo-driver/bson/primitive" +import ( + "time" -type UserModel struct { - ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"` - Name string `json:"name,omitempty"` - Email string `json:"email,omitempty"` - Password string `json:"password,omitempty"` - AvatarImage string `json:"avatarimage,omitempty"` + "go.mongodb.org/mongo-driver/bson/primitive" +) + +type User struct { + ID primitive.ObjectID `json:"_id" bson:"_id"` + Name *string `json:"name" validate:"required,min=2,max=100"` + Email *string `json:"email" validate:"required,email"` + Password *string `json:"password"` + Token *string `json:"token"` + RefreshToken *string `json:"refresh_token"` + UserType *string `json:"user_type" validate:"required,eq=ADMIN|eq=USER"` + AvatarImage *string `json:"avatar_image"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + UserId string `json:"user_id"` } diff --git a/server/router/router.go b/server/router/router.go deleted file mode 100644 index f2c99c5..0000000 --- a/server/router/router.go +++ /dev/null @@ -1,16 +0,0 @@ -package router - -import ( - "github/Yash-Khattar/yogzen-server/controller" - - "github.com/gorilla/mux" -) - -func Router() *mux.Router { - router := mux.NewRouter() - router.HandleFunc("/auth/signup", controller.SignUp).Methods("POST") - router.HandleFunc("/auth/signin", controller.SignIn).Methods("POST") - router.HandleFunc("/auth/verifytoken/{token}", controller.VerifyToken).Methods("GET") - - return router -} diff --git a/server/routes/authRouter.go b/server/routes/authRouter.go new file mode 100644 index 0000000..5afef96 --- /dev/null +++ b/server/routes/authRouter.go @@ -0,0 +1,12 @@ +package routes + +import ( + controller "github/Yash-Khattar/yogzen-server/controller" + + "github.com/gin-gonic/gin" +) + +func AuthRouter(incomingRouter *gin.Engine) { + incomingRouter.POST("auth/signup", controller.Signup()) + incomingRouter.POST("auth/login", controller.Login()) +} diff --git a/server/routes/router.go b/server/routes/router.go new file mode 100644 index 0000000..2e914c3 --- /dev/null +++ b/server/routes/router.go @@ -0,0 +1,19 @@ +// package router + +// import ( +// "github/Yash-Khattar/yogzen-server/controller" + +// "github.com/gorilla/mux" +// ) + +// func Router() *mux.Router { +// router := mux.NewRouter() +// router.HandleFunc("/auth/signup", controller.SignUp).Methods("POST") +// router.HandleFunc("/auth/signin", controller.SignIn).Methods("POST") +// router.HandleFunc("/auth/verifytoken/{token}", controller.VerifyToken).Methods("GET") + +// return router +// } + +package routes + diff --git a/server/routes/userRouter.go b/server/routes/userRouter.go new file mode 100644 index 0000000..3867433 --- /dev/null +++ b/server/routes/userRouter.go @@ -0,0 +1,15 @@ +package routes + +import ( + controller "github/Yash-Khattar/yogzen-server/controller" + + "github/Yash-Khattar/yogzen-server/middleware" + + "github.com/gin-gonic/gin" +) + +func UserRoutes(incomingRoutes *gin.Engine) { + incomingRoutes.Use(middleware.Authenticate()) + // incomingRoutes.GET("/users", controller.GetUsers()) + incomingRoutes.GET("/users/:user_id", controller.GetUser()) +}