Conversation
|
@claude review |
|
Claude finished @GodPuffin's task in 2m 19s —— View job Code Review
Overall this is a well-structured feature with good separation of concerns: the Bugs
newMembership.Set("created", artificialMembership.GetDateTime("created"))In PocketBase, SecurityClaim POST endpoint accepts unauthenticated requests without CSRF protection
e.POST("/claim-member/:token", memberships.HandleClaimMember(app))This route has no CSRF protection. A malicious page could POST to HTTP scheme detection unreliable behind a reverse proxy
func absoluteClaimLink(scheme, host, token string) string {
if scheme == "" {
scheme = "http"
}
...
return fmt.Sprintf("%s://%s%s", scheme, host, memberclaim.Path(token))
}
Data IntegrityNo composite unique index on
The migration adds a unique constraint on Minor IssuesTemplate: claim token in URL not URL-encoded
<a href="/login?claim={{.claim_token}}">...
<a href="/register?claim={{.claim_token}}">...Go templates HTML-escape values in attribute context but don't URL-encode them. The Router test doesn't cover all routes
The test's expected map omits
missingTransferPrerequisite := errors.New("membership transfer prerequisite not found")Defining a sentinel error inside a function body is unusual — it creates a new distinct error value on every request, which makes it impossible to inspect outside the handler. It works here because it's only compared with What's Done Well
|
Summary
member_claim_linksPocketBase collection and shared transfer logicTesting
go test ./...