mirror of
https://github.com/pocket-id/pocket-id.git
synced 2025-12-16 10:13:01 +03:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e44b5e367 | ||
|
|
8a1db0cb4a | ||
|
|
3f02d08109 |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,3 +1,15 @@
|
|||||||
|
## [](https://github.com/stonith404/pocket-id/compare/v0.25.1...v) (2025-01-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* support wildcard callback URLs ([8a1db0c](https://github.com/stonith404/pocket-id/commit/8a1db0cb4a5d4b32b4fdc19d41fff688a7c71a56))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* non LDAP users get created with a empty LDAP ID string ([3f02d08](https://github.com/stonith404/pocket-id/commit/3f02d081098ad2caaa60a56eea4705639f80d01f))
|
||||||
|
|
||||||
## [](https://github.com/stonith404/pocket-id/compare/v0.25.0...v) (2025-01-19)
|
## [](https://github.com/stonith404/pocket-id/compare/v0.25.0...v) (2025-01-19)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type OidcClientDto struct {
|
|||||||
|
|
||||||
type OidcClientCreateDto struct {
|
type OidcClientCreateDto struct {
|
||||||
Name string `json:"name" binding:"required,max=50"`
|
Name string `json:"name" binding:"required,max=50"`
|
||||||
CallbackURLs []string `json:"callbackURLs" binding:"required,urlList"`
|
CallbackURLs []string `json:"callbackURLs" binding:"required"`
|
||||||
IsPublic bool `json:"isPublic"`
|
IsPublic bool `json:"isPublic"`
|
||||||
PkceEnabled bool `json:"pkceEnabled"`
|
PkceEnabled bool `json:"pkceEnabled"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,21 +4,9 @@ import (
|
|||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var validateUrlList validator.Func = func(fl validator.FieldLevel) bool {
|
|
||||||
urls := fl.Field().Interface().([]string)
|
|
||||||
for _, u := range urls {
|
|
||||||
_, err := url.ParseRequestURI(u)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
var validateUsername validator.Func = func(fl validator.FieldLevel) bool {
|
var validateUsername validator.Func = func(fl validator.FieldLevel) bool {
|
||||||
// [a-zA-Z0-9] : The username must start with an alphanumeric character
|
// [a-zA-Z0-9] : The username must start with an alphanumeric character
|
||||||
// [a-zA-Z0-9_.@-]* : The rest of the username can contain alphanumeric characters, dots, underscores, hyphens, and "@" symbols
|
// [a-zA-Z0-9_.@-]* : The rest of the username can contain alphanumeric characters, dots, underscores, hyphens, and "@" symbols
|
||||||
@@ -36,11 +24,6 @@ var validateClaimKey validator.Func = func(fl validator.FieldLevel) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
|
||||||
if err := v.RegisterValidation("urlList", validateUrlList); err != nil {
|
|
||||||
log.Fatalf("Failed to register custom validation: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
||||||
if err := v.RegisterValidation("username", validateUsername); err != nil {
|
if err := v.RegisterValidation("username", validateUsername); err != nil {
|
||||||
log.Fatalf("Failed to register custom validation: %v", err)
|
log.Fatalf("Failed to register custom validation: %v", err)
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ func handleValidationError(validationErrors validator.ValidationErrors) string {
|
|||||||
errorMessage = fmt.Sprintf("%s must be at least %s characters long", fieldName, ve.Param())
|
errorMessage = fmt.Sprintf("%s must be at least %s characters long", fieldName, ve.Param())
|
||||||
case "max":
|
case "max":
|
||||||
errorMessage = fmt.Sprintf("%s must be at most %s characters long", fieldName, ve.Param())
|
errorMessage = fmt.Sprintf("%s must be at most %s characters long", fieldName, ve.Param())
|
||||||
case "urlList":
|
|
||||||
errorMessage = fmt.Sprintf("%s must be a list of valid URLs", fieldName)
|
|
||||||
default:
|
default:
|
||||||
errorMessage = fmt.Sprintf("%s is invalid", fieldName)
|
errorMessage = fmt.Sprintf("%s is invalid", fieldName)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"os"
|
"os"
|
||||||
"slices"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -432,8 +432,16 @@ func (s *OidcService) getCallbackURL(client model.OidcClient, inputCallbackURL s
|
|||||||
if inputCallbackURL == "" {
|
if inputCallbackURL == "" {
|
||||||
return client.CallbackURLs[0], nil
|
return client.CallbackURLs[0], nil
|
||||||
}
|
}
|
||||||
if slices.Contains(client.CallbackURLs, inputCallbackURL) {
|
|
||||||
return inputCallbackURL, nil
|
for _, callbackPattern := range client.CallbackURLs {
|
||||||
|
regexPattern := strings.ReplaceAll(regexp.QuoteMeta(callbackPattern), `\*`, ".*") + "$"
|
||||||
|
matched, err := regexp.MatchString(regexPattern, inputCallbackURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if matched {
|
||||||
|
return inputCallbackURL, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", &common.OidcInvalidCallbackURLError{}
|
return "", &common.OidcInvalidCallbackURLError{}
|
||||||
|
|||||||
@@ -62,7 +62,10 @@ func (s *UserGroupService) Create(input dto.UserGroupCreateDto) (group model.Use
|
|||||||
group = model.UserGroup{
|
group = model.UserGroup{
|
||||||
FriendlyName: input.FriendlyName,
|
FriendlyName: input.FriendlyName,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
LdapID: &input.LdapID,
|
}
|
||||||
|
|
||||||
|
if input.LdapID != "" {
|
||||||
|
group.LdapID = &input.LdapID
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.db.Preload("Users").Create(&group).Error; err != nil {
|
if err := s.db.Preload("Users").Create(&group).Error; err != nil {
|
||||||
|
|||||||
@@ -66,8 +66,11 @@ func (s *UserService) CreateUser(input dto.UserCreateDto) (model.User, error) {
|
|||||||
Email: input.Email,
|
Email: input.Email,
|
||||||
Username: input.Username,
|
Username: input.Username,
|
||||||
IsAdmin: input.IsAdmin,
|
IsAdmin: input.IsAdmin,
|
||||||
LdapID: &input.LdapID,
|
|
||||||
}
|
}
|
||||||
|
if input.LdapID != "" {
|
||||||
|
user.LdapID = &input.LdapID
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.db.Create(&user).Error; err != nil {
|
if err := s.db.Create(&user).Error; err != nil {
|
||||||
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||||
return model.User{}, s.checkDuplicatedFields(user)
|
return model.User{}, s.checkDuplicatedFields(user)
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
UPDATE users SET ldap_id = '' WHERE ldap_id IS NULL;
|
||||||
|
UPDATE user_groups SET ldap_id = '' WHERE ldap_id IS NULL;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
UPDATE users SET ldap_id = null WHERE ldap_id = '';
|
||||||
|
UPDATE user_groups SET ldap_id = null WHERE ldap_id = '';
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
UPDATE users SET ldap_id = '' WHERE ldap_id IS NULL;
|
||||||
|
UPDATE user_groups SET ldap_id = '' WHERE ldap_id IS NULL;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
UPDATE users SET ldap_id = null WHERE ldap_id = '';
|
||||||
|
UPDATE user_groups SET ldap_id = null WHERE ldap_id = '';
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pocket-id-frontend",
|
"name": "pocket-id-frontend",
|
||||||
"version": "0.25.1",
|
"version": "0.26.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev --port 3000",
|
"dev": "vite dev --port 3000",
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
name: z.string().min(2).max(50),
|
name: z.string().min(2).max(50),
|
||||||
callbackURLs: z.array(z.string().url()).nonempty(),
|
callbackURLs: z.array(z.string()).nonempty(),
|
||||||
isPublic: z.boolean(),
|
isPublic: z.boolean(),
|
||||||
pkceEnabled: z.boolean()
|
pkceEnabled: z.boolean()
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user