diff --git a/.gitignore b/.gitignore
index 398baf2..66fd13c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,5 +13,3 @@
# Dependency directories (remove the comment below to include it)
# vendor/
-
-.idea
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/devicemngmt.iml b/.idea/devicemngmt.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/devicemngmt.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..660daf0
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/action_create.go b/action_create.go
index eebbd0e..8b23c5b 100644
--- a/action_create.go
+++ b/action_create.go
@@ -3,46 +3,47 @@ package devicemngmt
import (
"context"
"errors"
- "fmt"
"github.com/Selly-Modules/logger"
"github.com/Selly-Modules/mongodb"
+ ua "github.com/mssola/user_agent"
+ "go.mongodb.org/mongo-driver/bson"
)
-// CreateOptions ...
-type CreateOptions struct {
+// DeviceCreate ...
+type DeviceCreate struct {
DeviceID string
UserID string
UserAgent string
AppVersion string
IP string
FCMToken string
- AuthToken string
Language string
}
// Create ...
-func (s Service) Create(payload CreateOptions) error {
+func (s Service) Create(payload DeviceCreate) error {
var (
col = s.getDeviceCollection()
ctx = context.Background()
)
- // Validate payload
- err := payload.validate()
- if err != nil {
- return err
- }
-
// New device data from payload
deviceData, err := payload.newDevice()
if err != nil {
return err
}
- // Find deviceID existed or not
- if s.isDeviceIDExisted(ctx, deviceData.DeviceID) {
- return errors.New("this device is already existed")
+ // Find device id existed or not
+ device := Device{}
+ if err = col.FindOne(ctx, bson.M{"deviceID": deviceData.DeviceID}).Decode(&device); err != nil {
+ logger.Error("devicemngt - findByDeviceID", logger.LogData{
+ "deviceID": deviceData.DeviceID,
+ "err": err.Error(),
+ })
+ }
+ if !device.ID.IsZero() {
+ return errors.New("deviceID already exists")
}
// Create device
@@ -52,33 +53,78 @@ func (s Service) Create(payload CreateOptions) error {
"doc": deviceData,
"err": err.Error(),
})
- return fmt.Errorf("error when create device: %s", err.Error())
+ return errors.New("create device fail")
}
return nil
}
-func (payload CreateOptions) newDevice() (result Device, err error) {
+func (payload DeviceCreate) newDevice() (result Device, err error) {
timeNow := now()
device := Device{
- ID: mongodb.NewObjectID(),
- DeviceID: payload.DeviceID,
- OSName: getOSName(payload.UserAgent),
- OSVersion: getOSVersion(payload.UserAgent),
- IP: payload.IP,
- Language: getLanguage(payload.Language),
- AuthToken: payload.AuthToken,
- LastActivatedAt: timeNow,
- CreatedAt: timeNow,
- FCMToken: payload.FCMToken,
+ ID: mongodb.NewObjectID(),
+ LastActivityAt: timeNow,
+ CreatedAt: timeNow,
+ FCMToken: payload.FCMToken,
}
+ // Set deviceID
+ if payload.DeviceID == "" {
+ logger.Error("devicemngt - Create: no deviceID data", logger.LogData{
+ "payload": payload,
+ })
+ err = errors.New("no deviceID data")
+ return
+ }
+ device.DeviceID = payload.DeviceID
+
+ // OSName, OSVersion
+ if payload.UserAgent == "" {
+ logger.Error("devicemngt - Create: no userAgent data", logger.LogData{
+ "payload": payload,
+ })
+ err = errors.New("no userAgent data")
+ return
+ }
+ uaData := ua.New(payload.UserAgent)
+ device.OSName = uaData.OSInfo().Name
+ device.OSVersion = uaData.OSInfo().Version
+
// App version
if payload.AppVersion != "" {
device.AppVersion = payload.AppVersion
device.IsMobile = true
}
+ // IP
+ if payload.IP == "" {
+ logger.Error("devicemngt - Create: no ip data", logger.LogData{
+ "payload": payload,
+ })
+ err = errors.New("no ip data")
+ return
+ }
+
+ // Language, default is vietnamese(vi)
+ if payload.Language == "" {
+ device.Language = viLanguage
+ } else {
+ device.Language = enLanguage
+ }
+
+ // userIDe
+ userID, _ := mongodb.NewIDFromString(payload.UserID)
+ if userID.IsZero() {
+ logger.Error("devicemngt - Create: invalid userID data", logger.LogData{
+ "payload": payload,
+ })
+ err = errors.New("invalid userID data")
+ return
+ }
+
+ // Generate authToken from userID
+ device.AuthToken = s.generateAuthToken(userID)
+
result = device
return
}
diff --git a/auth_token.go b/auth_token.go
new file mode 100644
index 0000000..88c7ddd
--- /dev/null
+++ b/auth_token.go
@@ -0,0 +1,17 @@
+package devicemngmt
+
+import (
+ "time"
+
+ "github.com/dgrijalva/jwt-go"
+ "go.mongodb.org/mongo-driver/bson/primitive"
+)
+
+func (s Service) generateAuthToken(userID primitive.ObjectID) string {
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
+ "_id": userID,
+ "exp": now().Add(time.Second * 15552000).Unix(), // 6 months
+ })
+ tokenString, _ := token.SignedString([]byte(s.AuthSecret))
+ return tokenString
+}
diff --git a/constant.go b/constant.go
index ca4c13f..a6e1949 100644
--- a/constant.go
+++ b/constant.go
@@ -2,10 +2,10 @@ package devicemngmt
// Constant ...
const (
- tableDevice = "devices"
+ TableDevice = "devices"
timezoneHCM = "Asia/Ho_Chi_Minh"
- langVi = "vi"
- langEn = "en"
+ viLanguage = "vi"
+ enLanguage = "en"
)
diff --git a/devicemngt.go b/devicemngt.go
index cc2b7e7..3574ec1 100644
--- a/devicemngt.go
+++ b/devicemngt.go
@@ -19,6 +19,8 @@ type Config struct {
MongoDB MongoDBConfig
// Table prefix, each service has its own prefix
TablePrefix string
+ // Auth secret, used to sign token
+ AuthSecret string
}
// Service ...
@@ -30,9 +32,9 @@ type Service struct {
var s *Service
// Init ...
-func Init(config Config) (*Service, error) {
- if config.MongoDB.Host == "" || config.TablePrefix == "" {
- return nil, errors.New("please provide all necessary information for init device")
+func Init(config Config) error {
+ if config.MongoDB.Host == "" || config.TablePrefix == "" || config.AuthSecret == "" {
+ return errors.New("please provide all necessary information for init device")
}
// Connect MongoDB
@@ -46,7 +48,7 @@ func Init(config Config) (*Service, error) {
)
if err != nil {
fmt.Println("Cannot init module DEVICE MANAGEMENT", err)
- return nil, err
+ return err
}
s = &Service{
@@ -54,7 +56,7 @@ func Init(config Config) (*Service, error) {
DB: db,
}
- return s, nil
+ return nil
}
// GetInstance ...
diff --git a/helper.go b/helper.go
index 120e9d5..9b7a54f 100644
--- a/helper.go
+++ b/helper.go
@@ -1,50 +1,12 @@
package devicemngmt
import (
- "context"
"fmt"
- "github.com/Selly-Modules/logger"
- ua "github.com/mssola/user_agent"
- "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
// getDeviceCollection ...
func (s Service) getDeviceCollection() *mongo.Collection {
- return s.DB.Collection(fmt.Sprintf("%s-%s", s.TablePrefix, tableDevice))
-}
-
-func (s Service) isDeviceIDExisted(ctx context.Context, deviceID string) bool {
- var (
- col = s.getDeviceCollection()
- device = Device{}
- )
-
- if err := col.FindOne(ctx, bson.M{"deviceID": deviceID}).Decode(&device); err != nil {
- logger.Error("devicemngt - findByDeviceID", logger.LogData{
- "deviceID": deviceID,
- "err": err.Error(),
- })
- return true
- }
- return !device.ID.IsZero()
-}
-
-func getOSName(userAgent string) string {
- uaData := ua.New(userAgent)
- return uaData.OSInfo().Name
-}
-
-func getOSVersion(userAgent string) string {
- uaData := ua.New(userAgent)
- return uaData.OSInfo().Version
-}
-
-func getLanguage(lang string) string {
- // Language, default is vietnamese(vi)
- if lang == langEn {
- return langEn
- }
- return langVi
+ return s.DB.Collection(fmt.Sprintf("%s-%s", s.TablePrefix, TableDevice))
}
diff --git a/model.go b/model.go
index 7c00d78..bd684f3 100644
--- a/model.go
+++ b/model.go
@@ -8,17 +8,17 @@ import (
// Device ...
type Device struct {
- ID primitive.ObjectID `bson:"_id" json:"_id"`
- DeviceID string `bson:"deviceID" json:"deviceId"` // unique
- IP string `bson:"ip" json:"ip"`
- OSName string `bson:"osName" json:"osName"`
- OSVersion string `bson:"osVersion" json:"osVersion"`
- AppVersion string `bson:"appVersion" json:"appVersion"`
- Language string `bson:"language" json:"language"` // vi, en
- IsMobile bool `bson:"isMobile" json:"isMobile"`
- LastActivatedAt time.Time `bson:"lastActivatedAt" json:"lastActivatedAt"`
- UserID primitive.ObjectID `bson:"userID" json:"userId"`
- AuthToken string `bson:"authToken" json:"authToken"`
- FCMToken string `bson:"fcmToken" json:"fcmToken"`
- CreatedAt time.Time `bson:"createdAt" json:"createdAt"`
+ ID primitive.ObjectID `bson:"_id"`
+ DeviceID string `bson:"deviceID"` // unique
+ IP string `bson:"ip"`
+ OSName string `bson:"osName"`
+ OSVersion string `bson:"osVersion"`
+ AppVersion string `bson:"appVersion"`
+ Language string `bson:"language"` // vi, en
+ IsMobile bool `bson:"isMobile"`
+ LastActivityAt time.Time `bson:"lastActivityAt"`
+ UserID primitive.ObjectID `bson:"userID"`
+ AuthToken string `bson:"authToken"`
+ FCMToken string `bson:"fcmToken"`
+ CreatedAt time.Time `bson:"createdAt"`
}
diff --git a/validate.go b/validate.go
deleted file mode 100644
index 9efc49f..0000000
--- a/validate.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package devicemngmt
-
-import (
- "errors"
-
- "github.com/Selly-Modules/logger"
-)
-
-func (co CreateOptions) validate() error{
- // DeviceID
- if co.DeviceID == "" {
- logger.Error("devicemngt - Create: no deviceID data", logger.LogData{
- "payload": co,
- })
- return errors.New("no deviceID data")
- }
-
- // UserAgent
- if co.UserAgent == "" {
- logger.Error("devicemngt - Create: no userAgent data", logger.LogData{
- "payload": co,
- })
- return errors.New("no userAgent data")
- }
-
- // IP
- if co.IP == "" {
- logger.Error("devicemngt - Create: no ip data", logger.LogData{
- "payload": co,
- })
- return errors.New("no ip data")
- }
-
- // UserID
- if co.UserID == "" {
- logger.Error("devicemngt - Create: no userID data", logger.LogData{
- "payload": co,
- })
- return errors.New("no userID data")
- }
-
- // AuthToken
- if co.AuthToken == "" {
- logger.Error("devicemngt - Create: no authToken data", logger.LogData{
- "payload": co,
- })
- return errors.New("no authToken data")
- }
-
- return nil
-}