@@ -21,6 +21,7 @@ type IUserRepo interface {
2121 ActivateAccount (c context.Context , email string , code string ) (bool , error )
2222 UpdatePasswordByToken (ctx context.Context , email string , token string , password string ) error
2323 CreateAppToken (c context.Context , userID int , name string , scopes []models.ApiTokenScope , days int ) (* models.AppToken , error )
24+ GetAppTokenByID (c context.Context , tokenId int ) (* models.AppToken , error )
2425 GetAllUserTokens (c context.Context , userID int ) ([]* models.AppToken , error )
2526 DeleteAppToken (c context.Context , userID int , tokenID string ) error
2627 UpdateNotificationSettings (c context.Context , userID int , provider models.NotificationProvider , triggers models.NotificationTriggerOptions ) error
@@ -160,43 +161,62 @@ func convertScopesToStringArray(scopes []models.ApiTokenScope) []string {
160161}
161162
162163func (r * UserRepository ) CreateAppToken (c context.Context , userID int , name string , scopes []models.ApiTokenScope , days int ) (* models.AppToken , error ) {
163- duration := time .Duration (days ) * 24 * time .Hour
164- expiresAt := time .Now ().UTC ().Add (duration )
165- jwtToken := jwt .NewWithClaims (jwt .SigningMethodHS256 , jwt.MapClaims {
166- auth .IdentityKey : fmt .Sprintf ("%d" , userID ),
167- "exp" : expiresAt .Unix (),
168- "type" : "app" ,
169- "scopes" : scopes ,
170- })
164+ var token * models.AppToken
165+ err := r .db .WithContext (c ).Transaction (func (tx * gorm.DB ) error {
166+ var nextID int
167+ if err := tx .Raw ("SELECT COALESCE(MAX(id), 0)+1 AS next_id FROM app_tokens" ).Scan (& nextID ).Error ; err != nil {
168+ return fmt .Errorf ("failed to get next token id: %w" , err )
169+ }
171170
172- signedToken , err := jwtToken . SignedString ([] byte ( r . cfg . Jwt . Secret ))
173- if err != nil {
174- return nil , fmt .Errorf ("failed to sign token: %s" , err . Error () )
175- }
171+ for _ , scope := range scopes {
172+ if scope == models . ApiTokenScopeUserRead || scope == models . ApiTokenScopeUserWrite {
173+ return fmt .Errorf ("user scopes are not allowed" )
174+ }
176175
177- for _ , scope := range scopes {
178- if scope == models . ApiTokenScopeUserRead || scope == models . ApiTokenScopeUserWrite {
179- return nil , fmt . Errorf ( "user scopes are not allowed" )
176+ if scope == models . ApiTokenScopeTokenWrite {
177+ return fmt . Errorf ( "token scopes are not allowed" )
178+ }
180179 }
181180
182- if scope == models .ApiTokenScopeTokenWrite {
183- return nil , fmt .Errorf ("token scopes are not allowed" )
181+ duration := time .Duration (days ) * 24 * time .Hour
182+ expiresAt := time .Now ().UTC ().Add (duration )
183+ jwtToken := jwt .NewWithClaims (jwt .SigningMethodHS256 , jwt.MapClaims {
184+ auth .AppTokenKey : fmt .Sprintf ("%d" , nextID ),
185+ auth .IdentityKey : fmt .Sprintf ("%d" , userID ),
186+ "exp" : expiresAt .Unix (),
187+ "type" : "app" ,
188+ "scopes" : scopes ,
189+ })
190+
191+ signedToken , err := jwtToken .SignedString ([]byte (r .cfg .Jwt .Secret ))
192+ if err != nil {
193+ return fmt .Errorf ("failed to sign token: %s" , err .Error ())
184194 }
185- }
186195
187- token := & models.AppToken {
188- UserID : userID ,
189- Name : name ,
190- Token : signedToken ,
191- ExpiresAt : expiresAt ,
192- Scopes : convertScopesToStringArray (scopes ),
193- }
196+ token = & models.AppToken {
197+ ID : nextID ,
198+ UserID : userID ,
199+ Name : name ,
200+ Token : signedToken ,
201+ ExpiresAt : expiresAt ,
202+ Scopes : convertScopesToStringArray (scopes ),
203+ }
194204
195- if err := r .db .WithContext (c ).Create (token ).Error ; err != nil {
196- return nil , fmt .Errorf ("failed to save token: %s" , err .Error ())
197- }
205+ if err := tx .Create (token ).Error ; err != nil {
206+ return fmt .Errorf ("failed to save token: %s" , err .Error ())
207+ }
208+ return nil
209+ })
198210
199- return token , nil
211+ return token , err
212+ }
213+
214+ func (r * UserRepository ) GetAppTokenByID (c context.Context , tokenId int ) (* models.AppToken , error ) {
215+ var token models.AppToken
216+ if err := r .db .WithContext (c ).Where ("id = ?" , tokenId ).First (& token ).Error ; err != nil {
217+ return nil , err
218+ }
219+ return & token , nil
200220}
201221
202222func (r * UserRepository ) GetAllUserTokens (c context.Context , userID int ) ([]* models.AppToken , error ) {
0 commit comments