mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-03-22 18:30:09 +00:00
feat: add JWT ID for generated tokens (#1322)
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/lestrrat-go/jwx/v3/jwa"
|
"github.com/lestrrat-go/jwx/v3/jwa"
|
||||||
"github.com/lestrrat-go/jwx/v3/jwk"
|
"github.com/lestrrat-go/jwx/v3/jwk"
|
||||||
"github.com/lestrrat-go/jwx/v3/jwt"
|
"github.com/lestrrat-go/jwx/v3/jwt"
|
||||||
@@ -193,6 +194,7 @@ func (s *JwtService) GenerateAccessToken(user model.User) (string, error) {
|
|||||||
Expiration(now.Add(s.appConfigService.GetDbConfig().SessionDuration.AsDurationMinutes())).
|
Expiration(now.Add(s.appConfigService.GetDbConfig().SessionDuration.AsDurationMinutes())).
|
||||||
IssuedAt(now).
|
IssuedAt(now).
|
||||||
Issuer(s.envConfig.AppURL).
|
Issuer(s.envConfig.AppURL).
|
||||||
|
JwtID(uuid.New().String()).
|
||||||
Build()
|
Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to build token: %w", err)
|
return "", fmt.Errorf("failed to build token: %w", err)
|
||||||
@@ -247,6 +249,7 @@ func (s *JwtService) BuildIDToken(userClaims map[string]any, clientID string, no
|
|||||||
Expiration(now.Add(1 * time.Hour)).
|
Expiration(now.Add(1 * time.Hour)).
|
||||||
IssuedAt(now).
|
IssuedAt(now).
|
||||||
Issuer(s.envConfig.AppURL).
|
Issuer(s.envConfig.AppURL).
|
||||||
|
JwtID(uuid.New().String()).
|
||||||
Build()
|
Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to build token: %w", err)
|
return nil, fmt.Errorf("failed to build token: %w", err)
|
||||||
@@ -336,6 +339,7 @@ func (s *JwtService) BuildOAuthAccessToken(user model.User, clientID string) (jw
|
|||||||
Expiration(now.Add(1 * time.Hour)).
|
Expiration(now.Add(1 * time.Hour)).
|
||||||
IssuedAt(now).
|
IssuedAt(now).
|
||||||
Issuer(s.envConfig.AppURL).
|
Issuer(s.envConfig.AppURL).
|
||||||
|
JwtID(uuid.New().String()).
|
||||||
Build()
|
Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to build token: %w", err)
|
return nil, fmt.Errorf("failed to build token: %w", err)
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import (
|
|||||||
|
|
||||||
const testEncryptionKey = "0123456789abcdef0123456789abcdef"
|
const testEncryptionKey = "0123456789abcdef0123456789abcdef"
|
||||||
|
|
||||||
|
const uuidRegexPattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
||||||
|
|
||||||
func newTestEnvConfig() *common.EnvConfigSchema {
|
func newTestEnvConfig() *common.EnvConfigSchema {
|
||||||
return &common.EnvConfigSchema{
|
return &common.EnvConfigSchema{
|
||||||
AppURL: "https://test.example.com",
|
AppURL: "https://test.example.com",
|
||||||
@@ -323,6 +325,9 @@ func TestGenerateVerifyAccessToken(t *testing.T) {
|
|||||||
audience, ok := claims.Audience()
|
audience, ok := claims.Audience()
|
||||||
_ = assert.True(t, ok, "Audience not found in token") &&
|
_ = assert.True(t, ok, "Audience not found in token") &&
|
||||||
assert.Equal(t, []string{service.envConfig.AppURL}, audience, "Audience should contain the app URL")
|
assert.Equal(t, []string{service.envConfig.AppURL}, audience, "Audience should contain the app URL")
|
||||||
|
jwtID, ok := claims.JwtID()
|
||||||
|
_ = assert.True(t, ok, "JWT ID not found in token") &&
|
||||||
|
assert.Regexp(t, uuidRegexPattern, jwtID, "JWT ID is not a UUID")
|
||||||
|
|
||||||
expectedExp := time.Now().Add(1 * time.Hour)
|
expectedExp := time.Now().Add(1 * time.Hour)
|
||||||
expiration, ok := claims.Expiration()
|
expiration, ok := claims.Expiration()
|
||||||
@@ -520,6 +525,9 @@ func TestGenerateVerifyIdToken(t *testing.T) {
|
|||||||
issuer, ok := claims.Issuer()
|
issuer, ok := claims.Issuer()
|
||||||
_ = assert.True(t, ok, "Issuer not found in token") &&
|
_ = assert.True(t, ok, "Issuer not found in token") &&
|
||||||
assert.Equal(t, service.envConfig.AppURL, issuer, "Issuer should match app URL")
|
assert.Equal(t, service.envConfig.AppURL, issuer, "Issuer should match app URL")
|
||||||
|
jwtID, ok := claims.JwtID()
|
||||||
|
_ = assert.True(t, ok, "JWT ID not found in token") &&
|
||||||
|
assert.Regexp(t, uuidRegexPattern, jwtID, "JWT ID is not a UUID")
|
||||||
|
|
||||||
expectedExp := time.Now().Add(1 * time.Hour)
|
expectedExp := time.Now().Add(1 * time.Hour)
|
||||||
expiration, ok := claims.Expiration()
|
expiration, ok := claims.Expiration()
|
||||||
@@ -754,6 +762,9 @@ func TestGenerateVerifyOAuthAccessToken(t *testing.T) {
|
|||||||
issuer, ok := claims.Issuer()
|
issuer, ok := claims.Issuer()
|
||||||
_ = assert.True(t, ok, "Issuer not found in token") &&
|
_ = assert.True(t, ok, "Issuer not found in token") &&
|
||||||
assert.Equal(t, service.envConfig.AppURL, issuer, "Issuer should match app URL")
|
assert.Equal(t, service.envConfig.AppURL, issuer, "Issuer should match app URL")
|
||||||
|
jwtID, ok := claims.JwtID()
|
||||||
|
_ = assert.True(t, ok, "JWT ID not found in token") &&
|
||||||
|
assert.Regexp(t, uuidRegexPattern, jwtID, "JWT ID is not a UUID")
|
||||||
|
|
||||||
expectedExp := time.Now().Add(1 * time.Hour)
|
expectedExp := time.Now().Add(1 * time.Hour)
|
||||||
expiration, ok := claims.Expiration()
|
expiration, ok := claims.Expiration()
|
||||||
|
|||||||
Reference in New Issue
Block a user