2023-09-04 03:33:13 +02:00
|
|
|
package database
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/golang-jwt/jwt/v4"
|
|
|
|
"github.com/oklog/ulid/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
const InternalApplicationName = "mercury_internal"
|
|
|
|
const TokenCookieName = "mercury_token"
|
|
|
|
|
|
|
|
type Application struct {
|
|
|
|
ID ulid.ULID
|
|
|
|
Name string
|
|
|
|
}
|
|
|
|
|
|
|
|
type Token struct {
|
|
|
|
ID ulid.ULID
|
|
|
|
AppID ulid.ULID
|
|
|
|
UserID ulid.ULID
|
2023-09-04 17:32:45 +02:00
|
|
|
Scopes TokenScopes
|
2023-09-04 03:33:13 +02:00
|
|
|
Expires time.Time
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t Token) ToClaims() TokenClaims {
|
|
|
|
createdAt := ulid.Time(t.ID.Time())
|
|
|
|
|
|
|
|
return TokenClaims{
|
|
|
|
TokenID: t.ID,
|
|
|
|
UserID: t.UserID,
|
|
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
|
|
Issuer: "mercury",
|
|
|
|
ExpiresAt: jwt.NewNumericDate(t.Expires),
|
|
|
|
IssuedAt: jwt.NewNumericDate(createdAt),
|
|
|
|
NotBefore: jwt.NewNumericDate(createdAt),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type TokenClaims struct {
|
|
|
|
TokenID ulid.ULID `json:"jti"`
|
|
|
|
UserID ulid.ULID `json:"sub"`
|
|
|
|
jwt.RegisteredClaims
|
|
|
|
}
|
2023-09-04 17:32:45 +02:00
|
|
|
|
|
|
|
type TokenScope string
|
|
|
|
|
|
|
|
const (
|
|
|
|
// All scopes below
|
|
|
|
TokenScopeAll TokenScope = "all"
|
|
|
|
TokenScopeAccountsRead TokenScope = "accounts.read"
|
|
|
|
// Controls whether tokens have access to sensitive account data, NOT if they can use `/accounts/@me` endpoints.
|
|
|
|
TokenScopeAccountsMe TokenScope = "accounts.me"
|
|
|
|
TokenScopeAccountsWrite TokenScope = "accounts.write"
|
2023-09-06 02:40:50 +02:00
|
|
|
TokenScopeBlogsRead TokenScope = "blogs.read"
|
|
|
|
TokenScopeBlogsWrite TokenScope = "blogs.write"
|
2023-09-06 16:32:33 +02:00
|
|
|
TokenScopePostsRead TokenScope = "posts.read"
|
|
|
|
TokenScopePostsWrite TokenScope = "posts.write"
|
|
|
|
TokenScopeTimeline TokenScope = "timeline"
|
2023-10-16 15:08:36 +02:00
|
|
|
TokenScopeStreaming TokenScope = "streaming"
|
2023-09-04 17:32:45 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func (s TokenScope) IsValid() bool {
|
|
|
|
switch s {
|
2023-10-16 15:08:36 +02:00
|
|
|
case TokenScopeAccountsRead, TokenScopeAccountsMe,
|
|
|
|
TokenScopeAccountsWrite, TokenScopeBlogsRead,
|
|
|
|
TokenScopeBlogsWrite, TokenScopePostsRead,
|
|
|
|
TokenScopePostsWrite, TokenScopeTimeline,
|
|
|
|
TokenScopeStreaming:
|
2023-09-04 17:32:45 +02:00
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type TokenScopes []TokenScope
|
|
|
|
|
|
|
|
func (s TokenScopes) Has(scope TokenScope) bool {
|
|
|
|
for i := range s {
|
|
|
|
if s[i] == scope || s[i] == TokenScopeAll {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|