Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
07d1839112 | |||
876872f363 | |||
11e062549a | |||
6a9fcb1c18 | |||
07365fda73 | |||
2264b64007 | |||
bb389ad429 | |||
b6967abd08 | |||
f886bd7eb8 | |||
b638d9cdf4 | |||
8af0675247 | |||
fd09b18033 | |||
129a9cf48c | |||
feadf879dd | |||
9c134f4c8f | |||
b624576269 | |||
2d980380e5 | |||
fda2a3436d | |||
6f96e5e0c8 | |||
dadf42c09b | |||
e855f8c5ad | |||
01ec5900d4 | |||
850fbbaa36 | |||
820b8fc379 | |||
a90279221c | |||
ad988575b3 | |||
994a90c8fb | |||
f33dcba284 | |||
84ddafeb84 | |||
d8903875d3 | |||
fb3267d139 | |||
aaed0a747f |
2
.github/workflows/backend-tests.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Test
|
||||
name: Backend Test
|
||||
|
||||
on:
|
||||
push:
|
||||
|
49
.github/workflows/extension-test.yml
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
name: Extension Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "release/v*.*.*"
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "extension/**"
|
||||
|
||||
jobs:
|
||||
eslint-checks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: pnpm/action-setup@v2.2.4
|
||||
with:
|
||||
version: 8
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
cache: pnpm
|
||||
cache-dependency-path: "extension/pnpm-lock.yaml"
|
||||
- run: pnpm install
|
||||
working-directory: extension
|
||||
- name: Run eslint check
|
||||
run: pnpm lint
|
||||
working-directory: extension
|
||||
|
||||
extension-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: pnpm/action-setup@v2.2.4
|
||||
with:
|
||||
version: 8
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "18"
|
||||
cache: pnpm
|
||||
cache-dependency-path: "extension/pnpm-lock.yaml"
|
||||
- run: pnpm install
|
||||
working-directory: extension
|
||||
- name: Run extension build
|
||||
run: pnpm build
|
||||
working-directory: extension
|
2
.github/workflows/frontend-test.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Test
|
||||
name: Frontend Test
|
||||
|
||||
on:
|
||||
push:
|
||||
|
@ -1,7 +1,10 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -16,9 +19,46 @@ const (
|
||||
|
||||
// CookieExpDuration expires slightly earlier than the jwt expiration. Client would be logged out if the user
|
||||
// cookie expires, thus the client would always logout first before attempting to make a request with the expired jwt.
|
||||
// Suppose we have a valid refresh token, we will refresh the token in cases:
|
||||
// 1. The access token has already expired, we refresh the token so that the ongoing request can pass through.
|
||||
CookieExpDuration = AccessTokenDuration - 1*time.Minute
|
||||
// AccessTokenCookieName is the cookie name of access token.
|
||||
AccessTokenCookieName = "slash.access-token"
|
||||
)
|
||||
|
||||
type ClaimsMessage struct {
|
||||
Name string `json:"name"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// GenerateAccessToken generates an access token.
|
||||
// username is the email of the user.
|
||||
func GenerateAccessToken(username string, userID int32, expirationTime time.Time, secret string) (string, error) {
|
||||
return generateToken(username, userID, AccessTokenAudienceName, expirationTime, []byte(secret))
|
||||
}
|
||||
|
||||
// generateToken generates a jwt token.
|
||||
func generateToken(username string, userID int32, audience string, expirationTime time.Time, secret []byte) (string, error) {
|
||||
registeredClaims := jwt.RegisteredClaims{
|
||||
Issuer: Issuer,
|
||||
Audience: jwt.ClaimStrings{audience},
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
Subject: fmt.Sprint(userID),
|
||||
}
|
||||
if expirationTime.After(time.Now()) {
|
||||
registeredClaims.ExpiresAt = jwt.NewNumericDate(expirationTime)
|
||||
}
|
||||
|
||||
// Declare the token with the HS256 algorithm used for signing, and the claims.
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, &ClaimsMessage{
|
||||
Name: username,
|
||||
RegisteredClaims: registeredClaims,
|
||||
})
|
||||
token.Header["kid"] = KeyID
|
||||
|
||||
// Create the JWT string.
|
||||
tokenString, err := token.SignedString(secret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tokenString, nil
|
||||
}
|
||||
|
@ -1,12 +1,17 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/boojack/slash/api/auth"
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"github.com/boojack/slash/store"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
@ -46,9 +51,16 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "unmatched email and password")
|
||||
}
|
||||
|
||||
if err := GenerateTokensAndSetCookies(c, user, secret); err != nil {
|
||||
accessToken, err := auth.GenerateAccessToken(user.Email, user.ID, time.Now().Add(auth.AccessTokenDuration), secret)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to generate tokens, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
if err := s.UpsertAccessTokenToStore(ctx, user, accessToken); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to upsert access token, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
|
||||
cookieExp := time.Now().Add(auth.CookieExpDuration)
|
||||
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
|
||||
return c.JSON(http.StatusOK, convertUserFromStore(user))
|
||||
})
|
||||
|
||||
@ -95,10 +107,16 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to create user, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
|
||||
if err := GenerateTokensAndSetCookies(c, user, secret); err != nil {
|
||||
accessToken, err := auth.GenerateAccessToken(user.Email, user.ID, time.Now().Add(auth.AccessTokenDuration), secret)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to generate tokens, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
if err := s.UpsertAccessTokenToStore(ctx, user, accessToken); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to upsert access token, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
|
||||
cookieExp := time.Now().Add(auth.CookieExpDuration)
|
||||
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
|
||||
return c.JSON(http.StatusOK, convertUserFromStore(user))
|
||||
})
|
||||
|
||||
@ -108,3 +126,46 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *APIV1Service) UpsertAccessTokenToStore(ctx context.Context, user *store.User, accessToken string) error {
|
||||
userAccessTokens, err := s.Store.GetUserAccessTokens(ctx, user.ID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get user access tokens")
|
||||
}
|
||||
userAccessToken := storepb.AccessTokensUserSetting_AccessToken{
|
||||
AccessToken: accessToken,
|
||||
Description: "Account sign in",
|
||||
}
|
||||
userAccessTokens = append(userAccessTokens, &userAccessToken)
|
||||
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
|
||||
UserId: user.ID,
|
||||
Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
|
||||
Value: &storepb.UserSetting_AccessTokensUserSetting{
|
||||
AccessTokensUserSetting: &storepb.AccessTokensUserSetting{
|
||||
AccessTokens: userAccessTokens,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to upsert user setting, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveTokensAndCookies removes the jwt token from the cookies.
|
||||
func RemoveTokensAndCookies(c echo.Context) {
|
||||
cookieExp := time.Now().Add(-1 * time.Hour)
|
||||
setTokenCookie(c, auth.AccessTokenCookieName, "", cookieExp)
|
||||
}
|
||||
|
||||
// setTokenCookie sets the token to the cookie.
|
||||
func setTokenCookie(c echo.Context, name, token string, expiration time.Time) {
|
||||
cookie := new(http.Cookie)
|
||||
cookie.Name = name
|
||||
cookie.Value = token
|
||||
cookie.Expires = expiration
|
||||
cookie.Path = "/"
|
||||
// Http-only helps mitigate the risk of client side script accessing the protected cookie.
|
||||
cookie.HttpOnly = true
|
||||
cookie.SameSite = http.SameSiteStrictMode
|
||||
c.SetCookie(cookie)
|
||||
}
|
||||
|
101
api/v1/jwt.go
@ -4,10 +4,10 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/boojack/slash/api/auth"
|
||||
"github.com/boojack/slash/internal/util"
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"github.com/boojack/slash/store"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/labstack/echo/v4"
|
||||
@ -20,76 +20,6 @@ const (
|
||||
UserIDContextKey = "user-id"
|
||||
)
|
||||
|
||||
type claimsMessage struct {
|
||||
Name string `json:"name"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// GenerateAccessToken generates an access token for web.
|
||||
func GenerateAccessToken(username string, userID int32, secret string) (string, error) {
|
||||
expirationTime := time.Now().Add(auth.AccessTokenDuration)
|
||||
return generateToken(username, userID, auth.AccessTokenAudienceName, expirationTime, []byte(secret))
|
||||
}
|
||||
|
||||
// GenerateTokensAndSetCookies generates jwt token and saves it to the http-only cookie.
|
||||
func GenerateTokensAndSetCookies(c echo.Context, user *store.User, secret string) error {
|
||||
accessToken, err := GenerateAccessToken(user.Email, user.ID, secret)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to generate access token")
|
||||
}
|
||||
|
||||
cookieExp := time.Now().Add(auth.CookieExpDuration)
|
||||
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveTokensAndCookies removes the jwt token and refresh token from the cookies.
|
||||
func RemoveTokensAndCookies(c echo.Context) {
|
||||
cookieExp := time.Now().Add(-1 * time.Hour)
|
||||
setTokenCookie(c, auth.AccessTokenCookieName, "", cookieExp)
|
||||
}
|
||||
|
||||
// setTokenCookie sets the token to the cookie.
|
||||
func setTokenCookie(c echo.Context, name, token string, expiration time.Time) {
|
||||
cookie := new(http.Cookie)
|
||||
cookie.Name = name
|
||||
cookie.Value = token
|
||||
cookie.Expires = expiration
|
||||
cookie.Path = "/"
|
||||
// Http-only helps mitigate the risk of client side script accessing the protected cookie.
|
||||
cookie.HttpOnly = true
|
||||
cookie.SameSite = http.SameSiteStrictMode
|
||||
c.SetCookie(cookie)
|
||||
}
|
||||
|
||||
// generateToken generates a jwt token.
|
||||
func generateToken(username string, userID int32, aud string, expirationTime time.Time, secret []byte) (string, error) {
|
||||
// Create the JWT claims, which includes the username and expiry time.
|
||||
claims := &claimsMessage{
|
||||
Name: username,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
Audience: jwt.ClaimStrings{aud},
|
||||
// In JWT, the expiry time is expressed as unix milliseconds.
|
||||
ExpiresAt: jwt.NewNumericDate(expirationTime),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
Issuer: auth.Issuer,
|
||||
Subject: fmt.Sprint(userID),
|
||||
},
|
||||
}
|
||||
|
||||
// Declare the token with the HS256 algorithm used for signing, and the claims.
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
token.Header["kid"] = auth.KeyID
|
||||
|
||||
// Create the JWT string.
|
||||
tokenString, err := token.SignedString(secret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tokenString, nil
|
||||
}
|
||||
|
||||
func extractTokenFromHeader(c echo.Context) (string, error) {
|
||||
authHeader := c.Request().Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
@ -127,9 +57,7 @@ func audienceContains(audience jwt.ClaimStrings, token string) bool {
|
||||
}
|
||||
|
||||
// JWTMiddleware validates the access token.
|
||||
// If the access token is about to expire or has expired and the request has a valid refresh token, it
|
||||
// will try to generate new access token and refresh token.
|
||||
func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) echo.HandlerFunc {
|
||||
func JWTMiddleware(s *APIV1Service, next echo.HandlerFunc, secret string) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
path := c.Request().URL.Path
|
||||
@ -149,7 +77,7 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Missing access token")
|
||||
}
|
||||
|
||||
claims := &claimsMessage{}
|
||||
claims := &auth.ClaimsMessage{}
|
||||
_, err := jwt.ParseWithClaims(token, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, errors.Errorf("unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
|
||||
@ -161,23 +89,29 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
|
||||
}
|
||||
return nil, errors.Errorf("unexpected access token kid=%v", t.Header["kid"])
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
RemoveTokensAndCookies(c)
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, errors.Wrap(err, "Invalid or expired access token"))
|
||||
}
|
||||
if !audienceContains(claims.Audience, auth.AccessTokenAudienceName) {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, fmt.Sprintf("Invalid access token, audience mismatch, got %q, expected %q.", claims.Audience, auth.AccessTokenAudienceName))
|
||||
}
|
||||
|
||||
// We either have a valid access token or we will attempt to generate new access token and refresh token
|
||||
// We either have a valid access token or we will attempt to generate new access token.
|
||||
userID, err := util.ConvertStringToInt32(claims.Subject)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Malformed ID in the token.").WithInternal(err)
|
||||
}
|
||||
|
||||
accessTokens, err := s.Store.GetUserAccessTokens(ctx, userID)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to get user access tokens.").WithInternal(err)
|
||||
}
|
||||
if !validateAccessToken(token, accessTokens) {
|
||||
return echo.NewHTTPError(http.StatusUnauthorized, "Invalid access token.")
|
||||
}
|
||||
|
||||
// Even if there is no error, we still need to make sure the user still exists.
|
||||
user, err := server.Store.GetUser(ctx, &store.FindUser{
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
@ -192,3 +126,12 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
|
||||
func validateAccessToken(accessTokenString string, userAccessTokens []*storepb.AccessTokensUserSetting_AccessToken) bool {
|
||||
for _, userAccessToken := range userAccessTokens {
|
||||
if accessTokenString == userAccessToken.AccessToken {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -3,12 +3,11 @@ package v2
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/boojack/slash/api/auth"
|
||||
"github.com/boojack/slash/internal/util"
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"github.com/boojack/slash/store"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/pkg/errors"
|
||||
@ -18,9 +17,7 @@ import (
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var authenticationAllowlistMethods = map[string]bool{
|
||||
"/memos.api.v2.UserService/GetUser": true,
|
||||
}
|
||||
var authenticationAllowlistMethods = map[string]bool{}
|
||||
|
||||
// IsAuthenticationAllowed returns whether the method is exempted from authentication.
|
||||
func IsAuthenticationAllowed(fullMethodName string) bool {
|
||||
@ -41,14 +38,14 @@ const (
|
||||
|
||||
// GRPCAuthInterceptor is the auth interceptor for gRPC server.
|
||||
type GRPCAuthInterceptor struct {
|
||||
store *store.Store
|
||||
Store *store.Store
|
||||
secret string
|
||||
}
|
||||
|
||||
// NewGRPCAuthInterceptor returns a new API auth interceptor.
|
||||
func NewGRPCAuthInterceptor(store *store.Store, secret string) *GRPCAuthInterceptor {
|
||||
return &GRPCAuthInterceptor{
|
||||
store: store,
|
||||
Store: store,
|
||||
secret: secret,
|
||||
}
|
||||
}
|
||||
@ -59,12 +56,12 @@ func (in *GRPCAuthInterceptor) AuthenticationInterceptor(ctx context.Context, re
|
||||
if !ok {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "failed to parse metadata from incoming context")
|
||||
}
|
||||
accessTokenStr, err := getTokenFromMetadata(md)
|
||||
accessToken, err := getTokenFromMetadata(md)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, err.Error())
|
||||
return nil, status.Errorf(codes.Unauthenticated, "failed to get access token from metadata: %v", err)
|
||||
}
|
||||
|
||||
userID, err := in.authenticate(ctx, accessTokenStr)
|
||||
userID, err := in.authenticate(ctx, accessToken)
|
||||
if err != nil {
|
||||
if IsAuthenticationAllowed(serverInfo.FullMethod) {
|
||||
return handler(ctx, request)
|
||||
@ -72,6 +69,14 @@ func (in *GRPCAuthInterceptor) AuthenticationInterceptor(ctx context.Context, re
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userAccessTokens, err := in.Store.GetUserAccessTokens(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user access tokens")
|
||||
}
|
||||
if !validateAccessToken(accessToken, userAccessTokens) {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "invalid access token")
|
||||
}
|
||||
|
||||
// Stores userID into context.
|
||||
childCtx := context.WithValue(ctx, UserIDContextKey, userID)
|
||||
return handler(childCtx, request)
|
||||
@ -81,7 +86,7 @@ func (in *GRPCAuthInterceptor) authenticate(ctx context.Context, accessTokenStr
|
||||
if accessTokenStr == "" {
|
||||
return 0, status.Errorf(codes.Unauthenticated, "access token not found")
|
||||
}
|
||||
claims := &claimsMessage{}
|
||||
claims := &auth.ClaimsMessage{}
|
||||
_, err := jwt.ParseWithClaims(accessTokenStr, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
|
||||
@ -108,7 +113,7 @@ func (in *GRPCAuthInterceptor) authenticate(ctx context.Context, accessTokenStr
|
||||
if err != nil {
|
||||
return 0, status.Errorf(codes.Unauthenticated, "malformed ID %q in the access token", claims.Subject)
|
||||
}
|
||||
user, err := in.store.GetUser(ctx, &store.FindUser{
|
||||
user, err := in.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
@ -125,15 +130,16 @@ func (in *GRPCAuthInterceptor) authenticate(ctx context.Context, accessTokenStr
|
||||
}
|
||||
|
||||
func getTokenFromMetadata(md metadata.MD) (string, error) {
|
||||
// Try to get the token from the authorization header first.
|
||||
authorizationHeaders := md.Get("Authorization")
|
||||
if len(md.Get("Authorization")) > 0 {
|
||||
if len(authorizationHeaders) > 0 {
|
||||
authHeaderParts := strings.Fields(authorizationHeaders[0])
|
||||
if len(authHeaderParts) != 2 || strings.ToLower(authHeaderParts[0]) != "bearer" {
|
||||
return "", errors.Errorf("authorization header format must be Bearer {token}")
|
||||
}
|
||||
return authHeaderParts[1], nil
|
||||
}
|
||||
// check the HTTP cookie
|
||||
// Try to get the token from the cookie header.
|
||||
var accessToken string
|
||||
for _, t := range append(md.Get("grpcgateway-cookie"), md.Get("cookie")...) {
|
||||
header := http.Header{}
|
||||
@ -155,40 +161,11 @@ func audienceContains(audience jwt.ClaimStrings, token string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type claimsMessage struct {
|
||||
Name string `json:"name"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// GenerateAccessToken generates an access token for web.
|
||||
func GenerateAccessToken(username string, userID int, secret string) (string, error) {
|
||||
expirationTime := time.Now().Add(auth.AccessTokenDuration)
|
||||
return generateToken(username, userID, auth.AccessTokenAudienceName, expirationTime, []byte(secret))
|
||||
}
|
||||
|
||||
func generateToken(username string, userID int, aud string, expirationTime time.Time, secret []byte) (string, error) {
|
||||
// Create the JWT claims, which includes the username and expiry time.
|
||||
claims := &claimsMessage{
|
||||
Name: username,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
Audience: jwt.ClaimStrings{aud},
|
||||
// In JWT, the expiry time is expressed as unix milliseconds.
|
||||
ExpiresAt: jwt.NewNumericDate(expirationTime),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
Issuer: auth.Issuer,
|
||||
Subject: strconv.Itoa(userID),
|
||||
},
|
||||
func validateAccessToken(accessTokenString string, userAccessTokens []*storepb.AccessTokensUserSetting_AccessToken) bool {
|
||||
for _, userAccessToken := range userAccessTokens {
|
||||
if accessTokenString == userAccessToken.AccessToken {
|
||||
return true
|
||||
}
|
||||
|
||||
// Declare the token with the HS256 algorithm used for signing, and the claims.
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
token.Header["kid"] = auth.KeyID
|
||||
|
||||
// Create the JWT string.
|
||||
tokenString, err := token.SignedString(secret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tokenString, nil
|
||||
return false
|
||||
}
|
97
api/v2/shortcut_service.go
Normal file
@ -0,0 +1,97 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"github.com/boojack/slash/store"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type ShortcutService struct {
|
||||
apiv2pb.UnimplementedShortcutServiceServer
|
||||
|
||||
Secret string
|
||||
Store *store.Store
|
||||
}
|
||||
|
||||
// NewShortcutService creates a new Shortcut service.
|
||||
func NewShortcutService(secret string, store *store.Store) *ShortcutService {
|
||||
return &ShortcutService{
|
||||
Secret: secret,
|
||||
Store: store,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ShortcutService) ListShortcuts(ctx context.Context, _ *apiv2pb.ListShortcutsRequest) (*apiv2pb.ListShortcutsResponse, error) {
|
||||
userID := ctx.Value(UserIDContextKey).(int32)
|
||||
find := &store.FindShortcut{}
|
||||
find.VisibilityList = []store.Visibility{store.VisibilityWorkspace, store.VisibilityPublic}
|
||||
visibleShortcutList, err := s.Store.ListShortcuts(ctx, find)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to fetch visible shortcut list, err: %v", err)
|
||||
}
|
||||
|
||||
find.VisibilityList = []store.Visibility{store.VisibilityPrivate}
|
||||
find.CreatorID = &userID
|
||||
shortcutList, err := s.Store.ListShortcuts(ctx, find)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to fetch private shortcut list, err: %v", err)
|
||||
}
|
||||
|
||||
shortcutList = append(shortcutList, visibleShortcutList...)
|
||||
shortcuts := []*apiv2pb.Shortcut{}
|
||||
for _, shortcut := range shortcutList {
|
||||
shortcuts = append(shortcuts, convertShortcutFromStorepb(shortcut))
|
||||
}
|
||||
|
||||
response := &apiv2pb.ListShortcutsResponse{
|
||||
Shortcuts: shortcuts,
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *ShortcutService) GetShortcut(ctx context.Context, request *apiv2pb.GetShortcutRequest) (*apiv2pb.GetShortcutResponse, error) {
|
||||
shortcut, err := s.Store.GetShortcut(ctx, &store.FindShortcut{
|
||||
Name: &request.Name,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get shortcut by name: %v", err)
|
||||
}
|
||||
if shortcut == nil {
|
||||
return nil, status.Errorf(codes.NotFound, "shortcut not found")
|
||||
}
|
||||
|
||||
userID := ctx.Value(UserIDContextKey).(int32)
|
||||
if shortcut.Visibility == storepb.Visibility_PRIVATE && shortcut.CreatorId != userID {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "Permission denied")
|
||||
}
|
||||
shortcutMessage := convertShortcutFromStorepb(shortcut)
|
||||
response := &apiv2pb.GetShortcutResponse{
|
||||
Shortcut: shortcutMessage,
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func convertShortcutFromStorepb(shortcut *storepb.Shortcut) *apiv2pb.Shortcut {
|
||||
return &apiv2pb.Shortcut{
|
||||
Id: shortcut.Id,
|
||||
CreatorId: shortcut.CreatorId,
|
||||
CreatedTs: shortcut.CreatedTs,
|
||||
UpdatedTs: shortcut.UpdatedTs,
|
||||
RowStatus: apiv2pb.RowStatus(shortcut.RowStatus),
|
||||
Name: shortcut.Name,
|
||||
Link: shortcut.Link,
|
||||
Title: shortcut.Title,
|
||||
Tags: shortcut.Tags,
|
||||
Description: shortcut.Description,
|
||||
Visibility: apiv2pb.Visibility(shortcut.Visibility),
|
||||
OgMetadata: &apiv2pb.OpenGraphMetadata{
|
||||
Title: shortcut.OgMetadata.Title,
|
||||
Description: shortcut.OgMetadata.Description,
|
||||
Image: shortcut.OgMetadata.Image,
|
||||
},
|
||||
}
|
||||
}
|
@ -3,21 +3,29 @@ package v2
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/boojack/slash/api/auth"
|
||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"github.com/boojack/slash/store"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/exp/slices"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
type UserService struct {
|
||||
apiv2pb.UnimplementedUserServiceServer
|
||||
|
||||
Secret string
|
||||
Store *store.Store
|
||||
}
|
||||
|
||||
// NewUserService creates a new UserService.
|
||||
func NewUserService(store *store.Store) *UserService {
|
||||
func NewUserService(secret string, store *store.Store) *UserService {
|
||||
return &UserService{
|
||||
Secret: secret,
|
||||
Store: store,
|
||||
}
|
||||
}
|
||||
@ -27,7 +35,7 @@ func (s *UserService) GetUser(ctx context.Context, request *apiv2pb.GetUserReque
|
||||
ID: &request.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list tags: %v", err)
|
||||
return nil, status.Errorf(codes.Internal, "failed to find user: %v", err)
|
||||
}
|
||||
if user == nil {
|
||||
return nil, status.Errorf(codes.NotFound, "user not found")
|
||||
@ -40,6 +48,169 @@ func (s *UserService) GetUser(ctx context.Context, request *apiv2pb.GetUserReque
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *UserService) ListUserAccessTokens(ctx context.Context, request *apiv2pb.ListUserAccessTokensRequest) (*apiv2pb.ListUserAccessTokensResponse, error) {
|
||||
userID := ctx.Value(UserIDContextKey).(int32)
|
||||
if userID != request.Id {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "Permission denied")
|
||||
}
|
||||
|
||||
userAccessTokens, err := s.Store.GetUserAccessTokens(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list access tokens: %v", err)
|
||||
}
|
||||
|
||||
accessTokens := []*apiv2pb.UserAccessToken{}
|
||||
for _, userAccessToken := range userAccessTokens {
|
||||
claims := &auth.ClaimsMessage{}
|
||||
_, err := jwt.ParseWithClaims(userAccessToken.AccessToken, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, errors.Errorf("unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
|
||||
}
|
||||
if kid, ok := t.Header["kid"].(string); ok {
|
||||
if kid == "v1" {
|
||||
return []byte(s.Secret), nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Errorf("unexpected access token kid=%v", t.Header["kid"])
|
||||
})
|
||||
if err != nil {
|
||||
// If the access token is invalid or expired, just ignore it.
|
||||
continue
|
||||
}
|
||||
|
||||
userAccessToken := &apiv2pb.UserAccessToken{
|
||||
AccessToken: userAccessToken.AccessToken,
|
||||
Description: userAccessToken.Description,
|
||||
IssuedAt: timestamppb.New(claims.IssuedAt.Time),
|
||||
}
|
||||
if claims.ExpiresAt != nil {
|
||||
userAccessToken.ExpiresAt = timestamppb.New(claims.ExpiresAt.Time)
|
||||
}
|
||||
accessTokens = append(accessTokens, userAccessToken)
|
||||
}
|
||||
|
||||
// Sort by issued time in descending order.
|
||||
slices.SortFunc(accessTokens, func(i, j *apiv2pb.UserAccessToken) bool {
|
||||
return i.IssuedAt.Seconds > j.IssuedAt.Seconds
|
||||
})
|
||||
response := &apiv2pb.ListUserAccessTokensResponse{
|
||||
AccessTokens: accessTokens,
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *UserService) CreateUserAccessToken(ctx context.Context, request *apiv2pb.CreateUserAccessTokenRequest) (*apiv2pb.CreateUserAccessTokenResponse, error) {
|
||||
userID := ctx.Value(UserIDContextKey).(int32)
|
||||
if userID != request.Id {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "Permission denied")
|
||||
}
|
||||
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to get user: %v", err)
|
||||
}
|
||||
if user == nil {
|
||||
return nil, status.Errorf(codes.NotFound, "user not found")
|
||||
}
|
||||
|
||||
accessToken, err := auth.GenerateAccessToken(user.Email, user.ID, request.UserAccessToken.ExpiresAt.AsTime(), s.Secret)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to generate access token: %v", err)
|
||||
}
|
||||
|
||||
claims := &auth.ClaimsMessage{}
|
||||
_, err = jwt.ParseWithClaims(accessToken, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, errors.Errorf("unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
|
||||
}
|
||||
if kid, ok := t.Header["kid"].(string); ok {
|
||||
if kid == "v1" {
|
||||
return []byte(s.Secret), nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Errorf("unexpected access token kid=%v", t.Header["kid"])
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to parse access token: %v", err)
|
||||
}
|
||||
|
||||
// Upsert the access token to user setting store.
|
||||
if err := s.UpsertAccessTokenToStore(ctx, user, accessToken, request.UserAccessToken.Description); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to upsert access token to store: %v", err)
|
||||
}
|
||||
|
||||
userAccessToken := &apiv2pb.UserAccessToken{
|
||||
AccessToken: accessToken,
|
||||
Description: request.UserAccessToken.Description,
|
||||
IssuedAt: timestamppb.New(claims.IssuedAt.Time),
|
||||
}
|
||||
if claims.ExpiresAt != nil {
|
||||
userAccessToken.ExpiresAt = timestamppb.New(claims.ExpiresAt.Time)
|
||||
}
|
||||
response := &apiv2pb.CreateUserAccessTokenResponse{
|
||||
AccessToken: userAccessToken,
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (s *UserService) DeleteUserAccessToken(ctx context.Context, request *apiv2pb.DeleteUserAccessTokenRequest) (*apiv2pb.DeleteUserAccessTokenResponse, error) {
|
||||
userID := ctx.Value(UserIDContextKey).(int32)
|
||||
if userID != request.Id {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "Permission denied")
|
||||
}
|
||||
|
||||
userAccessTokens, err := s.Store.GetUserAccessTokens(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list access tokens: %v", err)
|
||||
}
|
||||
updatedUserAccessTokens := []*storepb.AccessTokensUserSetting_AccessToken{}
|
||||
for _, userAccessToken := range userAccessTokens {
|
||||
if userAccessToken.AccessToken == request.AccessToken {
|
||||
continue
|
||||
}
|
||||
updatedUserAccessTokens = append(updatedUserAccessTokens, userAccessToken)
|
||||
}
|
||||
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
|
||||
UserId: userID,
|
||||
Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
|
||||
Value: &storepb.UserSetting_AccessTokensUserSetting{
|
||||
AccessTokensUserSetting: &storepb.AccessTokensUserSetting{
|
||||
AccessTokens: updatedUserAccessTokens,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err)
|
||||
}
|
||||
|
||||
return &apiv2pb.DeleteUserAccessTokenResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *UserService) UpsertAccessTokenToStore(ctx context.Context, user *store.User, accessToken, description string) error {
|
||||
userAccessTokens, err := s.Store.GetUserAccessTokens(ctx, user.ID)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get user access tokens")
|
||||
}
|
||||
userAccessToken := storepb.AccessTokensUserSetting_AccessToken{
|
||||
AccessToken: accessToken,
|
||||
Description: description,
|
||||
}
|
||||
userAccessTokens = append(userAccessTokens, &userAccessToken)
|
||||
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
|
||||
UserId: user.ID,
|
||||
Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
|
||||
Value: &storepb.UserSetting_AccessTokensUserSetting{
|
||||
AccessTokensUserSetting: &storepb.AccessTokensUserSetting{
|
||||
AccessTokens: userAccessTokens,
|
||||
},
|
||||
},
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "failed to upsert user setting")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertUserFromStore(user *store.User) *apiv2pb.User {
|
||||
return &apiv2pb.User{
|
||||
Id: int32(user.ID),
|
||||
|
@ -29,7 +29,8 @@ func NewAPIV2Service(secret string, profile *profile.Profile, store *store.Store
|
||||
authProvider.AuthenticationInterceptor,
|
||||
),
|
||||
)
|
||||
apiv2pb.RegisterUserServiceServer(grpcServer, NewUserService(store))
|
||||
apiv2pb.RegisterUserServiceServer(grpcServer, NewUserService(secret, store))
|
||||
apiv2pb.RegisterShortcutServiceServer(grpcServer, NewShortcutService(secret, store))
|
||||
|
||||
return &APIV2Service{
|
||||
Secret: secret,
|
||||
@ -61,6 +62,9 @@ func (s *APIV2Service) RegisterGateway(ctx context.Context, e *echo.Echo) error
|
||||
if err := apiv2pb.RegisterUserServiceHandler(context.Background(), gwMux, conn); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := apiv2pb.RegisterShortcutServiceHandler(context.Background(), gwMux, conn); err != nil {
|
||||
return err
|
||||
}
|
||||
e.Any("/api/v2/*", echo.WrapHandler(gwMux))
|
||||
|
||||
return nil
|
||||
|
BIN
docs/assets/extension-usage/copy-access-token.png
Normal file
After Width: | Height: | Size: 155 KiB |
BIN
docs/assets/extension-usage/create-access-token.png
Normal file
After Width: | Height: | Size: 154 KiB |
BIN
docs/assets/extension-usage/extension-screenshot.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
docs/assets/extension-usage/extension-setting-button.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
docs/assets/extension-usage/extension-setting-page.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
docs/assets/extension-usage/shortcut-url.png
Normal file
After Width: | Height: | Size: 38 KiB |
47
docs/install-browser-extension.md
Normal file
@ -0,0 +1,47 @@
|
||||
# The Browser Extension of Slash
|
||||
|
||||
Slash provides a browser extension to help you use your shortcuts in the search bar to go to the corresponding URL.
|
||||
|
||||
## How to use
|
||||
|
||||
### Generate an access token
|
||||
|
||||
1. Go to your Slash instance and sign in with your account.
|
||||
|
||||
2. Go to the settings page and click on the "Create" button to create an access token.
|
||||
|
||||

|
||||
|
||||
3. Copy the access token and save it somewhere safe.
|
||||
|
||||

|
||||
|
||||
### Install the extension
|
||||
|
||||
> **Note**: The extension is not published to the Chrome Web Store yet. You can install it from the source code.
|
||||
|
||||
For Chromuim based browsers, you can download the packed extension from the [resources](https://github.com/boojack/slash/tree/main/extension/resources).
|
||||
|
||||
For Firefox, we don't support the Firefox Add-ons platform yet. And we are working on it.
|
||||
|
||||
### Configure the extension
|
||||
|
||||
1. Click on the extension icon and click on the "Settings" button.
|
||||
|
||||

|
||||
|
||||
2. Enter your Slash's domain and paste the access token you generated in the previous step.
|
||||
|
||||

|
||||
|
||||
3. Click on the "Save" button to save the settings.
|
||||
|
||||
4. Click on the extension icon again, you will see a list of your shortcuts.
|
||||
|
||||

|
||||
|
||||
### Use your shortcuts in the search bar
|
||||
|
||||
You can use your shortcuts in the search bar of your browser. For example, if you have a shortcut named `gh` for [GitHub](https://github.com), you can type `s/gh` in the search bar and press `Enter` to go to [GitHub](https://github.com).
|
||||
|
||||

|
33
extension/.eslintrc.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
},
|
||||
"extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["react", "@typescript-eslint", "prettier"],
|
||||
"ignorePatterns": ["node_modules", "dist", "public"],
|
||||
"rules": {
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-explicit-any": ["off"],
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/jsx-no-target-blank": "off"
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
}
|
||||
}
|
38
extension/.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
#cache
|
||||
.turbo
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env*
|
||||
|
||||
out/
|
||||
build/
|
||||
dist/
|
||||
|
||||
.plasmo
|
||||
|
||||
# bpp - http://bpp.browser.market/
|
||||
keys.json
|
||||
|
||||
# typescript
|
||||
.tsbuildinfo
|
8
extension/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
printWidth: 140,
|
||||
useTabs: false,
|
||||
semi: true,
|
||||
singleQuote: false,
|
||||
plugins: [require.resolve("@trivago/prettier-plugin-sort-imports")],
|
||||
importOrder: ["<BUILTIN_MODULES>", "<THIRD_PARTY_MODULES>", "^@/((?!less).+)", "^[./]", "^(.+).css"],
|
||||
};
|
1
extension/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Slash Browser Extension
|
BIN
extension/assets/icon.png
Normal file
After Width: | Height: | Size: 83 KiB |
60
extension/package.json
Normal file
@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "slash-extexnsion",
|
||||
"displayName": "Slash",
|
||||
"version": "0.1.0",
|
||||
"description": "An open source, self-hosted bookmarks and link sharing platform. Save and share your links very easily.",
|
||||
"author": "steven",
|
||||
"scripts": {
|
||||
"dev": "plasmo dev",
|
||||
"build": "plasmo build",
|
||||
"package": "plasmo package",
|
||||
"lint": "eslint --ext .js,.ts,.tsx, src",
|
||||
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/joy": "5.0.0-beta.0",
|
||||
"@plasmohq/storage": "^1.7.2",
|
||||
"axios": "^1.4.0",
|
||||
"classnames": "^2.3.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lucide-react": "^0.264.0",
|
||||
"plasmo": "0.82.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"zustand": "^4.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@trivago/prettier-plugin-sort-imports": "4.1.0",
|
||||
"@types/chrome": "0.0.241",
|
||||
"@types/lodash-es": "^4.17.8",
|
||||
"@types/node": "20.4.2",
|
||||
"@types/react": "18.2.15",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
||||
"@typescript-eslint/parser": "^6.2.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^8.46.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.27.1",
|
||||
"postcss": "^8.4.27",
|
||||
"prettier": "2.6.2",
|
||||
"tailwindcss": "^3.3.3",
|
||||
"typescript": "5.1.6"
|
||||
},
|
||||
"manifest": {
|
||||
"host_permissions": [
|
||||
"http://*/*",
|
||||
"https://*/*"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
"activeTab",
|
||||
"scripting",
|
||||
"storage"
|
||||
]
|
||||
}
|
||||
}
|
7107
extension/pnpm-lock.yaml
generated
Normal file
10
extension/postcss.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
/* eslint-disable no-undef */
|
||||
/**
|
||||
* @type {import('postcss').ProcessOptions}
|
||||
*/
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
BIN
extension/resources/chrome-mv3-prod.zip
Normal file
53
extension/src/background.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import type { Shortcut } from "@/types/proto/api/v2/shortcut_service_pb";
|
||||
import { Storage } from "@plasmohq/storage";
|
||||
|
||||
const storage = new Storage();
|
||||
const urlRegex = /https?:\/\/s\/(.+)/;
|
||||
|
||||
chrome.tabs.onUpdated.addListener(async (tabId, _, tab) => {
|
||||
if (!tab.url) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shortcutName = getShortcutNameFromUrl(tab.url);
|
||||
if (shortcutName) {
|
||||
const shortcuts = (await storage.getItem<Shortcut[]>("shortcuts")) || [];
|
||||
const shortcut = shortcuts.find((shortcut) => shortcut.name === shortcutName);
|
||||
if (!shortcut) {
|
||||
return;
|
||||
}
|
||||
return chrome.tabs.update(tabId, { url: shortcut.link });
|
||||
}
|
||||
});
|
||||
|
||||
const getShortcutNameFromUrl = (urlString: string) => {
|
||||
const matchResult = urlRegex.exec(urlString);
|
||||
if (matchResult === null) {
|
||||
return getShortcutNameFromSearchUrl(urlString);
|
||||
}
|
||||
return matchResult[1];
|
||||
};
|
||||
|
||||
const getShortcutNameFromSearchUrl = (urlString: string) => {
|
||||
const url = new URL(urlString);
|
||||
if ((url.hostname === "www.google.com" || url.hostname === "www.bing.com") && url.pathname === "/search") {
|
||||
const params = new URLSearchParams(url.search);
|
||||
const shortcutName = params.get("q");
|
||||
if (typeof shortcutName === "string" && shortcutName.startsWith("s/")) {
|
||||
return shortcutName.slice(2);
|
||||
}
|
||||
} else if (url.hostname === "www.baidu.com" && url.pathname === "/s") {
|
||||
const params = new URLSearchParams(url.search);
|
||||
const shortcutName = params.get("wd");
|
||||
if (typeof shortcutName === "string" && shortcutName.startsWith("s/")) {
|
||||
return shortcutName.slice(2);
|
||||
}
|
||||
} else if (url.hostname === "duckduckgo.com" && url.pathname === "/") {
|
||||
const params = new URLSearchParams(url.search);
|
||||
const shortcutName = params.get("q");
|
||||
if (typeof shortcutName === "string" && shortcutName.startsWith("s/")) {
|
||||
return shortcutName.slice(2);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
};
|
3
extension/src/components/Icon.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import * as Icon from "lucide-react";
|
||||
|
||||
export default Icon;
|
49
extension/src/components/PullShortcutsButton.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import { Button } from "@mui/joy";
|
||||
import { useStorage } from "@plasmohq/storage/hook";
|
||||
import axios from "axios";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { ListShortcutsResponse } from "@/types/proto/api/v2/shortcut_service_pb";
|
||||
import "../style.css";
|
||||
import Icon from "./Icon";
|
||||
|
||||
const PullShortcutsButton = () => {
|
||||
const [domain] = useStorage("domain");
|
||||
const [accessToken] = useStorage("access_token");
|
||||
const [, setShortcuts] = useStorage("shortcuts");
|
||||
const [isPulling, setIsPulling] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (domain && accessToken) {
|
||||
handlePullShortcuts(true);
|
||||
}
|
||||
}, [domain, accessToken]);
|
||||
|
||||
const handlePullShortcuts = async (silence = false) => {
|
||||
try {
|
||||
setIsPulling(true);
|
||||
const {
|
||||
data: { shortcuts },
|
||||
} = await axios.get<ListShortcutsResponse>(`${domain}/api/v2/shortcuts`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
});
|
||||
setShortcuts(shortcuts);
|
||||
if (!silence) {
|
||||
toast.success("Shortcuts pulled");
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error("Failed to pull shortcuts, error: " + error.message);
|
||||
}
|
||||
setIsPulling(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Button loading={isPulling} color="neutral" variant="plain" size="sm" onClick={() => handlePullShortcuts()}>
|
||||
<Icon.RefreshCcw className="w-4 h-auto" />
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export default PullShortcutsButton;
|
77
extension/src/components/ShortcutView.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
import type { Shortcut } from "@/types/proto/api/v2/shortcut_service_pb";
|
||||
import { useStorage } from "@plasmohq/storage/hook";
|
||||
import classNames from "classnames";
|
||||
import { useEffect, useState } from "react";
|
||||
import useFaviconStore from "../stores/favicon";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
shortcut: Shortcut;
|
||||
}
|
||||
|
||||
const ShortcutView = (props: Props) => {
|
||||
const { shortcut } = props;
|
||||
const faviconStore = useFaviconStore();
|
||||
const [domain] = useStorage<string>("domain", "");
|
||||
const [favicon, setFavicon] = useState<string | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
faviconStore.getOrFetchUrlFavicon(shortcut.link).then((url) => {
|
||||
if (url) {
|
||||
setFavicon(url);
|
||||
}
|
||||
});
|
||||
}, [shortcut.link]);
|
||||
|
||||
const handleShortcutLinkClick = () => {
|
||||
const shortcutLink = `${domain}/s/${shortcut.name}`;
|
||||
chrome.tabs.create({ url: shortcutLink });
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={classNames(
|
||||
"group w-full px-3 py-2 flex flex-col justify-start items-start border rounded-lg hover:bg-gray-100 hover:shadow"
|
||||
)}
|
||||
>
|
||||
<div className="w-full flex flex-row justify-start items-center">
|
||||
<span className={classNames("w-5 h-5 flex justify-center items-center overflow-clip shrink-0")}>
|
||||
{favicon ? (
|
||||
<img className="w-full h-auto rounded-full" src={favicon} decoding="async" loading="lazy" />
|
||||
) : (
|
||||
<Icon.CircleSlash className="w-full h-auto text-gray-400" />
|
||||
)}
|
||||
</span>
|
||||
<div className="ml-1 w-[calc(100%-20px)] flex flex-col justify-start items-start">
|
||||
<div className="w-full flex flex-row justify-start items-center">
|
||||
<button
|
||||
className={classNames(
|
||||
"max-w-full flex flex-row px-1 mr-1 justify-start items-center cursor-pointer rounded-md hover:underline"
|
||||
)}
|
||||
onClick={handleShortcutLinkClick}
|
||||
>
|
||||
<div className="truncate">
|
||||
<span>{shortcut.title}</span>
|
||||
{shortcut.title ? (
|
||||
<span className="text-gray-400">(s/{shortcut.name})</span>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-gray-400">s/</span>
|
||||
<span className="truncate">{shortcut.name}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<span className="hidden group-hover:block ml-1 cursor-pointer shrink-0">
|
||||
<Icon.ExternalLink className="w-4 h-auto text-gray-600" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShortcutView;
|
18
extension/src/components/ShortcutsContainer.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import type { Shortcut } from "@/types/proto/api/v2/shortcut_service_pb";
|
||||
import { useStorage } from "@plasmohq/storage/hook";
|
||||
import classNames from "classnames";
|
||||
import ShortcutView from "./ShortcutView";
|
||||
|
||||
const ShortcutsContainer = () => {
|
||||
const [shortcuts] = useStorage<Shortcut[]>("shortcuts", (v) => (v ? v : []));
|
||||
|
||||
return (
|
||||
<div className={classNames("w-full grid grid-cols-2 gap-2")}>
|
||||
{shortcuts.map((shortcut) => {
|
||||
return <ShortcutView key={shortcut.id} shortcut={shortcut} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShortcutsContainer;
|
14
extension/src/helpers/api.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Storage } from "@plasmohq/storage";
|
||||
import axios from "axios";
|
||||
|
||||
const storage = new Storage();
|
||||
|
||||
export const getUrlFavicon = async (url: string) => {
|
||||
const domain = await storage.getItem<string>("domain");
|
||||
const accessToken = await storage.getItem<string>("access_token");
|
||||
return axios.get<string>(`${domain}/api/v1/url/favicon?url=${url}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
});
|
||||
};
|
5
extension/src/helpers/utils.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { isNull, isUndefined } from "lodash-es";
|
||||
|
||||
export const isNullorUndefined = (value: any) => {
|
||||
return isNull(value) || isUndefined(value);
|
||||
};
|
89
extension/src/options.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
import { Button, Input } from "@mui/joy";
|
||||
import { useStorage } from "@plasmohq/storage/hook";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Toaster, toast } from "react-hot-toast";
|
||||
import Icon from "./components/Icon";
|
||||
import "./style.css";
|
||||
|
||||
interface SettingState {
|
||||
domain: string;
|
||||
accessToken: string;
|
||||
}
|
||||
|
||||
const IndexOptions = () => {
|
||||
const [domain, setDomain] = useStorage<string>("domain", (v) => (v ? v : ""));
|
||||
const [accessToken, setAccessToken] = useStorage<string>("access_token", (v) => (v ? v : ""));
|
||||
const [settingState, setSettingState] = useState<SettingState>({
|
||||
domain,
|
||||
accessToken,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setSettingState({
|
||||
domain,
|
||||
accessToken,
|
||||
});
|
||||
}, [domain, accessToken]);
|
||||
|
||||
const setPartialSettingState = (partialSettingState: Partial<SettingState>) => {
|
||||
setSettingState((prevState) => ({
|
||||
...prevState,
|
||||
...partialSettingState,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSaveSetting = () => {
|
||||
setDomain(settingState.domain);
|
||||
setAccessToken(settingState.accessToken);
|
||||
toast.success("Setting saved");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full">
|
||||
<div className="w-full max-w-lg mx-auto flex flex-col justify-start items-start mt-12">
|
||||
<h2 className="flex flex-row justify-start items-center mb-6 font-mono">
|
||||
<Icon.CircleSlash className="w-8 h-auto mr-2 text-gray-500" />
|
||||
<span className="text-lg">Slash</span>
|
||||
<span className="mx-2 text-gray-400">/</span>
|
||||
<span className="text-lg">Setting</span>
|
||||
</h2>
|
||||
|
||||
<div className="w-full flex flex-col justify-start items-start mb-4">
|
||||
<span className="mb-2 text-base">Domain</span>
|
||||
<div className="relative w-full">
|
||||
<Input
|
||||
className="w-full"
|
||||
type="text"
|
||||
placeholder="The domain of your Slash instance"
|
||||
value={settingState.domain}
|
||||
onChange={(e) => setPartialSettingState({ domain: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<span className="mb-2 text-base">Access Token</span>
|
||||
<div className="relative w-full">
|
||||
<Input
|
||||
className="w-full"
|
||||
type="text"
|
||||
placeholder="The access token of your Slash instance"
|
||||
value={settingState.accessToken}
|
||||
onChange={(e) => setPartialSettingState({ accessToken: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full mt-6">
|
||||
<Button onClick={handleSaveSetting}>Save</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Toaster position="top-center" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndexOptions;
|
78
extension/src/popup.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import { Button } from "@mui/joy";
|
||||
import { useStorage } from "@plasmohq/storage/hook";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { Shortcut } from "@/types/proto/api/v2/shortcut_service_pb";
|
||||
import Icon from "./components/Icon";
|
||||
import PullShortcutsButton from "./components/PullShortcutsButton";
|
||||
import ShortcutsContainer from "./components/ShortcutsContainer";
|
||||
import "./style.css";
|
||||
|
||||
const IndexPopup = () => {
|
||||
const [domain] = useStorage<string>("domain", "");
|
||||
const [accessToken] = useStorage<string>("access_token", "");
|
||||
const [shortcuts] = useStorage<Shortcut[]>("shortcuts", []);
|
||||
const isInitialized = domain && accessToken;
|
||||
|
||||
const handleSettingButtonClick = () => {
|
||||
chrome.runtime.openOptionsPage();
|
||||
};
|
||||
|
||||
const handleRefreshButtonClick = () => {
|
||||
chrome.runtime.reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full min-w-[480px] p-4">
|
||||
<div className="w-full flex flex-row justify-between items-center text-sm">
|
||||
<div className="flex flex-row justify-start items-center font-mono">
|
||||
<Icon.CircleSlash className="w-5 h-auto mr-1 text-gray-500 -mt-0.5" />
|
||||
<span className="font-mono">Slash</span>
|
||||
{isInitialized && (
|
||||
<>
|
||||
<span className="mx-1 text-gray-400">/</span>
|
||||
<span>Shortcuts</span>
|
||||
<span className="mr-1 text-gray-500">({shortcuts.length})</span>
|
||||
<PullShortcutsButton />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Button size="sm" variant="plain" color="neutral" onClick={handleSettingButtonClick}>
|
||||
<Icon.Settings className="w-5 h-auto" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full mt-4">
|
||||
{isInitialized ? (
|
||||
shortcuts.length !== 0 ? (
|
||||
<ShortcutsContainer />
|
||||
) : (
|
||||
<div className="w-full flex flex-col justify-center items-center">
|
||||
<p>No shortcut found.</p>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<div className="w-full flex flex-col justify-start items-center">
|
||||
<p>No domain and access token found.</p>
|
||||
<div className="w-full flex flex-row justify-center items-center py-4">
|
||||
<Button size="sm" color="primary" onClick={handleSettingButtonClick}>
|
||||
<Icon.Settings className="w-5 h-auto mr-1" /> Setting
|
||||
</Button>
|
||||
<span className="mx-2">Or</span>
|
||||
<Button size="sm" variant="outlined" color="neutral" onClick={handleRefreshButtonClick}>
|
||||
<Icon.RefreshCcw className="w-5 h-auto mr-1" /> Refresh
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Toaster position="top-right" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndexPopup;
|
41
extension/src/stores/favicon.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
import { getUrlFavicon } from "../helpers/api";
|
||||
|
||||
interface FaviconState {
|
||||
cache: {
|
||||
[key: string]: string;
|
||||
};
|
||||
getOrFetchUrlFavicon: (url: string) => Promise<string>;
|
||||
}
|
||||
|
||||
const useFaviconStore = create<FaviconState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
cache: {},
|
||||
getOrFetchUrlFavicon: async (url: string) => {
|
||||
const cache = get().cache;
|
||||
if (cache[url]) {
|
||||
return cache[url];
|
||||
}
|
||||
|
||||
try {
|
||||
const { data: favicon } = await getUrlFavicon(url);
|
||||
if (favicon) {
|
||||
cache[url] = favicon;
|
||||
set(cache);
|
||||
return favicon;
|
||||
}
|
||||
} catch (error) {
|
||||
// do nothing
|
||||
}
|
||||
return "";
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "favicon_cache",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export default useFaviconStore;
|
25
extension/src/style.css
Normal file
@ -0,0 +1,25 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
body,
|
||||
html,
|
||||
#root {
|
||||
@apply text-base;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans", "Noto Sans CJK SC", "Microsoft YaHei UI", "Microsoft YaHei",
|
||||
"WenQuanYi Micro Hei", sans-serif, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for IE, Edge and Firefox */
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
}
|
25
extension/src/types/proto/api/v2/common_pb.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/common.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.RowStatus
|
||||
*/
|
||||
export declare enum RowStatus {
|
||||
/**
|
||||
* @generated from enum value: ROW_STATUS_UNSPECIFIED = 0;
|
||||
*/
|
||||
ROW_STATUS_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: NORMAL = 1;
|
||||
*/
|
||||
NORMAL = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: ARCHIVED = 2;
|
||||
*/
|
||||
ARCHIVED = 2,
|
||||
}
|
||||
|
19
extension/src/types/proto/api/v2/common_pb.js
Normal file
@ -0,0 +1,19 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/common.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.RowStatus
|
||||
*/
|
||||
export const RowStatus = proto3.makeEnum(
|
||||
"slash.api.v2.RowStatus",
|
||||
[
|
||||
{no: 0, name: "ROW_STATUS_UNSPECIFIED"},
|
||||
{no: 1, name: "NORMAL"},
|
||||
{no: 2, name: "ARCHIVED"},
|
||||
],
|
||||
);
|
||||
|
238
extension/src/types/proto/api/v2/shortcut_service_pb.d.ts
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/shortcut_service.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
|
||||
import { Message, proto3 } from "@bufbuild/protobuf";
|
||||
import type { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.Visibility
|
||||
*/
|
||||
export declare enum Visibility {
|
||||
/**
|
||||
* @generated from enum value: VISIBILITY_UNSPECIFIED = 0;
|
||||
*/
|
||||
VISIBILITY_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: PRIVATE = 1;
|
||||
*/
|
||||
PRIVATE = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: WORKSPACE = 2;
|
||||
*/
|
||||
WORKSPACE = 2,
|
||||
|
||||
/**
|
||||
* @generated from enum value: PUBLIC = 3;
|
||||
*/
|
||||
PUBLIC = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.Shortcut
|
||||
*/
|
||||
export declare class Shortcut extends Message<Shortcut> {
|
||||
/**
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @generated from field: int32 creator_id = 2;
|
||||
*/
|
||||
creatorId: number;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 created_ts = 3;
|
||||
*/
|
||||
createdTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 updated_ts = 4;
|
||||
*/
|
||||
updatedTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.RowStatus row_status = 5;
|
||||
*/
|
||||
rowStatus: RowStatus;
|
||||
|
||||
/**
|
||||
* @generated from field: string name = 6;
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string link = 7;
|
||||
*/
|
||||
link: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string title = 8;
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* @generated from field: repeated string tags = 9;
|
||||
*/
|
||||
tags: string[];
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 10;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.Visibility visibility = 11;
|
||||
*/
|
||||
visibility: Visibility;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.OpenGraphMetadata og_metadata = 12;
|
||||
*/
|
||||
ogMetadata?: OpenGraphMetadata;
|
||||
|
||||
constructor(data?: PartialMessage<Shortcut>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.Shortcut";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Shortcut;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Shortcut;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Shortcut;
|
||||
|
||||
static equals(a: Shortcut | PlainMessage<Shortcut> | undefined, b: Shortcut | PlainMessage<Shortcut> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.OpenGraphMetadata
|
||||
*/
|
||||
export declare class OpenGraphMetadata extends Message<OpenGraphMetadata> {
|
||||
/**
|
||||
* @generated from field: string title = 1;
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 2;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string image = 3;
|
||||
*/
|
||||
image: string;
|
||||
|
||||
constructor(data?: PartialMessage<OpenGraphMetadata>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.OpenGraphMetadata";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static equals(a: OpenGraphMetadata | PlainMessage<OpenGraphMetadata> | undefined, b: OpenGraphMetadata | PlainMessage<OpenGraphMetadata> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListShortcutsRequest
|
||||
*/
|
||||
export declare class ListShortcutsRequest extends Message<ListShortcutsRequest> {
|
||||
constructor(data?: PartialMessage<ListShortcutsRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.ListShortcutsRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListShortcutsRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListShortcutsRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListShortcutsRequest;
|
||||
|
||||
static equals(a: ListShortcutsRequest | PlainMessage<ListShortcutsRequest> | undefined, b: ListShortcutsRequest | PlainMessage<ListShortcutsRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListShortcutsResponse
|
||||
*/
|
||||
export declare class ListShortcutsResponse extends Message<ListShortcutsResponse> {
|
||||
/**
|
||||
* @generated from field: repeated slash.api.v2.Shortcut shortcuts = 1;
|
||||
*/
|
||||
shortcuts: Shortcut[];
|
||||
|
||||
constructor(data?: PartialMessage<ListShortcutsResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.ListShortcutsResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListShortcutsResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListShortcutsResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListShortcutsResponse;
|
||||
|
||||
static equals(a: ListShortcutsResponse | PlainMessage<ListShortcutsResponse> | undefined, b: ListShortcutsResponse | PlainMessage<ListShortcutsResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetShortcutRequest
|
||||
*/
|
||||
export declare class GetShortcutRequest extends Message<GetShortcutRequest> {
|
||||
/**
|
||||
* @generated from field: string name = 1;
|
||||
*/
|
||||
name: string;
|
||||
|
||||
constructor(data?: PartialMessage<GetShortcutRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.GetShortcutRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetShortcutRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetShortcutRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetShortcutRequest;
|
||||
|
||||
static equals(a: GetShortcutRequest | PlainMessage<GetShortcutRequest> | undefined, b: GetShortcutRequest | PlainMessage<GetShortcutRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetShortcutResponse
|
||||
*/
|
||||
export declare class GetShortcutResponse extends Message<GetShortcutResponse> {
|
||||
/**
|
||||
* @generated from field: slash.api.v2.Shortcut shortcut = 1;
|
||||
*/
|
||||
shortcut?: Shortcut;
|
||||
|
||||
constructor(data?: PartialMessage<GetShortcutResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.GetShortcutResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetShortcutResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetShortcutResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetShortcutResponse;
|
||||
|
||||
static equals(a: GetShortcutResponse | PlainMessage<GetShortcutResponse> | undefined, b: GetShortcutResponse | PlainMessage<GetShortcutResponse> | undefined): boolean;
|
||||
}
|
||||
|
92
extension/src/types/proto/api/v2/shortcut_service_pb.js
Normal file
@ -0,0 +1,92 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/shortcut_service.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
import { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.Visibility
|
||||
*/
|
||||
export const Visibility = proto3.makeEnum(
|
||||
"slash.api.v2.Visibility",
|
||||
[
|
||||
{no: 0, name: "VISIBILITY_UNSPECIFIED"},
|
||||
{no: 1, name: "PRIVATE"},
|
||||
{no: 2, name: "WORKSPACE"},
|
||||
{no: 3, name: "PUBLIC"},
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.Shortcut
|
||||
*/
|
||||
export const Shortcut = proto3.makeMessageType(
|
||||
"slash.api.v2.Shortcut",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "creator_id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 3, name: "created_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 4, name: "updated_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 5, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) },
|
||||
{ no: 6, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 7, name: "link", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 8, name: "title", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 9, name: "tags", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
||||
{ no: 10, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 11, name: "visibility", kind: "enum", T: proto3.getEnumType(Visibility) },
|
||||
{ no: 12, name: "og_metadata", kind: "message", T: OpenGraphMetadata },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.OpenGraphMetadata
|
||||
*/
|
||||
export const OpenGraphMetadata = proto3.makeMessageType(
|
||||
"slash.api.v2.OpenGraphMetadata",
|
||||
() => [
|
||||
{ no: 1, name: "title", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 3, name: "image", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListShortcutsRequest
|
||||
*/
|
||||
export const ListShortcutsRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.ListShortcutsRequest",
|
||||
[],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListShortcutsResponse
|
||||
*/
|
||||
export const ListShortcutsResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.ListShortcutsResponse",
|
||||
() => [
|
||||
{ no: 1, name: "shortcuts", kind: "message", T: Shortcut, repeated: true },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetShortcutRequest
|
||||
*/
|
||||
export const GetShortcutRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.GetShortcutRequest",
|
||||
() => [
|
||||
{ no: 1, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetShortcutResponse
|
||||
*/
|
||||
export const GetShortcutResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.GetShortcutResponse",
|
||||
() => [
|
||||
{ no: 1, name: "shortcut", kind: "message", T: Shortcut },
|
||||
],
|
||||
);
|
||||
|
327
extension/src/types/proto/api/v2/user_service_pb.d.ts
vendored
Normal file
@ -0,0 +1,327 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/user_service.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage, Timestamp } from "@bufbuild/protobuf";
|
||||
import { Message, proto3 } from "@bufbuild/protobuf";
|
||||
import type { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.Role
|
||||
*/
|
||||
export declare enum Role {
|
||||
/**
|
||||
* @generated from enum value: ROLE_UNSPECIFIED = 0;
|
||||
*/
|
||||
ROLE_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: ADMIN = 1;
|
||||
*/
|
||||
ADMIN = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: USER = 2;
|
||||
*/
|
||||
USER = 2,
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.User
|
||||
*/
|
||||
export declare class User extends Message<User> {
|
||||
/**
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.RowStatus row_status = 2;
|
||||
*/
|
||||
rowStatus: RowStatus;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 created_ts = 3;
|
||||
*/
|
||||
createdTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 updated_ts = 4;
|
||||
*/
|
||||
updatedTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.Role role = 6;
|
||||
*/
|
||||
role: Role;
|
||||
|
||||
/**
|
||||
* @generated from field: string email = 7;
|
||||
*/
|
||||
email: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string nickname = 8;
|
||||
*/
|
||||
nickname: string;
|
||||
|
||||
constructor(data?: PartialMessage<User>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.User";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): User;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): User;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): User;
|
||||
|
||||
static equals(a: User | PlainMessage<User> | undefined, b: User | PlainMessage<User> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetUserRequest
|
||||
*/
|
||||
export declare class GetUserRequest extends Message<GetUserRequest> {
|
||||
/**
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
constructor(data?: PartialMessage<GetUserRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.GetUserRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetUserRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetUserRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetUserRequest;
|
||||
|
||||
static equals(a: GetUserRequest | PlainMessage<GetUserRequest> | undefined, b: GetUserRequest | PlainMessage<GetUserRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetUserResponse
|
||||
*/
|
||||
export declare class GetUserResponse extends Message<GetUserResponse> {
|
||||
/**
|
||||
* @generated from field: slash.api.v2.User user = 1;
|
||||
*/
|
||||
user?: User;
|
||||
|
||||
constructor(data?: PartialMessage<GetUserResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.GetUserResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetUserResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetUserResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetUserResponse;
|
||||
|
||||
static equals(a: GetUserResponse | PlainMessage<GetUserResponse> | undefined, b: GetUserResponse | PlainMessage<GetUserResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListUserAccessTokensRequest
|
||||
*/
|
||||
export declare class ListUserAccessTokensRequest extends Message<ListUserAccessTokensRequest> {
|
||||
/**
|
||||
* id is the user id.
|
||||
*
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
constructor(data?: PartialMessage<ListUserAccessTokensRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.ListUserAccessTokensRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListUserAccessTokensRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListUserAccessTokensRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListUserAccessTokensRequest;
|
||||
|
||||
static equals(a: ListUserAccessTokensRequest | PlainMessage<ListUserAccessTokensRequest> | undefined, b: ListUserAccessTokensRequest | PlainMessage<ListUserAccessTokensRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListUserAccessTokensResponse
|
||||
*/
|
||||
export declare class ListUserAccessTokensResponse extends Message<ListUserAccessTokensResponse> {
|
||||
/**
|
||||
* @generated from field: repeated slash.api.v2.UserAccessToken access_tokens = 1;
|
||||
*/
|
||||
accessTokens: UserAccessToken[];
|
||||
|
||||
constructor(data?: PartialMessage<ListUserAccessTokensResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.ListUserAccessTokensResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListUserAccessTokensResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListUserAccessTokensResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListUserAccessTokensResponse;
|
||||
|
||||
static equals(a: ListUserAccessTokensResponse | PlainMessage<ListUserAccessTokensResponse> | undefined, b: ListUserAccessTokensResponse | PlainMessage<ListUserAccessTokensResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.CreateUserAccessTokenRequest
|
||||
*/
|
||||
export declare class CreateUserAccessTokenRequest extends Message<CreateUserAccessTokenRequest> {
|
||||
/**
|
||||
* id is the user id.
|
||||
*
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.UserAccessToken user_access_token = 2;
|
||||
*/
|
||||
userAccessToken?: UserAccessToken;
|
||||
|
||||
constructor(data?: PartialMessage<CreateUserAccessTokenRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.CreateUserAccessTokenRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateUserAccessTokenRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateUserAccessTokenRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateUserAccessTokenRequest;
|
||||
|
||||
static equals(a: CreateUserAccessTokenRequest | PlainMessage<CreateUserAccessTokenRequest> | undefined, b: CreateUserAccessTokenRequest | PlainMessage<CreateUserAccessTokenRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.CreateUserAccessTokenResponse
|
||||
*/
|
||||
export declare class CreateUserAccessTokenResponse extends Message<CreateUserAccessTokenResponse> {
|
||||
/**
|
||||
* @generated from field: slash.api.v2.UserAccessToken access_token = 1;
|
||||
*/
|
||||
accessToken?: UserAccessToken;
|
||||
|
||||
constructor(data?: PartialMessage<CreateUserAccessTokenResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.CreateUserAccessTokenResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateUserAccessTokenResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateUserAccessTokenResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateUserAccessTokenResponse;
|
||||
|
||||
static equals(a: CreateUserAccessTokenResponse | PlainMessage<CreateUserAccessTokenResponse> | undefined, b: CreateUserAccessTokenResponse | PlainMessage<CreateUserAccessTokenResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.DeleteUserAccessTokenRequest
|
||||
*/
|
||||
export declare class DeleteUserAccessTokenRequest extends Message<DeleteUserAccessTokenRequest> {
|
||||
/**
|
||||
* id is the user id.
|
||||
*
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* access_token is the access token to delete.
|
||||
*
|
||||
* @generated from field: string access_token = 2;
|
||||
*/
|
||||
accessToken: string;
|
||||
|
||||
constructor(data?: PartialMessage<DeleteUserAccessTokenRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.DeleteUserAccessTokenRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): DeleteUserAccessTokenRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): DeleteUserAccessTokenRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): DeleteUserAccessTokenRequest;
|
||||
|
||||
static equals(a: DeleteUserAccessTokenRequest | PlainMessage<DeleteUserAccessTokenRequest> | undefined, b: DeleteUserAccessTokenRequest | PlainMessage<DeleteUserAccessTokenRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.DeleteUserAccessTokenResponse
|
||||
*/
|
||||
export declare class DeleteUserAccessTokenResponse extends Message<DeleteUserAccessTokenResponse> {
|
||||
constructor(data?: PartialMessage<DeleteUserAccessTokenResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.DeleteUserAccessTokenResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): DeleteUserAccessTokenResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): DeleteUserAccessTokenResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): DeleteUserAccessTokenResponse;
|
||||
|
||||
static equals(a: DeleteUserAccessTokenResponse | PlainMessage<DeleteUserAccessTokenResponse> | undefined, b: DeleteUserAccessTokenResponse | PlainMessage<DeleteUserAccessTokenResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.UserAccessToken
|
||||
*/
|
||||
export declare class UserAccessToken extends Message<UserAccessToken> {
|
||||
/**
|
||||
* @generated from field: string access_token = 1;
|
||||
*/
|
||||
accessToken: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 2;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp issued_at = 3;
|
||||
*/
|
||||
issuedAt?: Timestamp;
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp expires_at = 4;
|
||||
*/
|
||||
expiresAt?: Timestamp;
|
||||
|
||||
constructor(data?: PartialMessage<UserAccessToken>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.UserAccessToken";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UserAccessToken;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): UserAccessToken;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): UserAccessToken;
|
||||
|
||||
static equals(a: UserAccessToken | PlainMessage<UserAccessToken> | undefined, b: UserAccessToken | PlainMessage<UserAccessToken> | undefined): boolean;
|
||||
}
|
||||
|
129
extension/src/types/proto/api/v2/user_service_pb.js
Normal file
@ -0,0 +1,129 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/user_service.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3, Timestamp } from "@bufbuild/protobuf";
|
||||
import { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.Role
|
||||
*/
|
||||
export const Role = proto3.makeEnum(
|
||||
"slash.api.v2.Role",
|
||||
[
|
||||
{no: 0, name: "ROLE_UNSPECIFIED"},
|
||||
{no: 1, name: "ADMIN"},
|
||||
{no: 2, name: "USER"},
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.User
|
||||
*/
|
||||
export const User = proto3.makeMessageType(
|
||||
"slash.api.v2.User",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) },
|
||||
{ no: 3, name: "created_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 4, name: "updated_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 6, name: "role", kind: "enum", T: proto3.getEnumType(Role) },
|
||||
{ no: 7, name: "email", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 8, name: "nickname", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetUserRequest
|
||||
*/
|
||||
export const GetUserRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.GetUserRequest",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetUserResponse
|
||||
*/
|
||||
export const GetUserResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.GetUserResponse",
|
||||
() => [
|
||||
{ no: 1, name: "user", kind: "message", T: User },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListUserAccessTokensRequest
|
||||
*/
|
||||
export const ListUserAccessTokensRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.ListUserAccessTokensRequest",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListUserAccessTokensResponse
|
||||
*/
|
||||
export const ListUserAccessTokensResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.ListUserAccessTokensResponse",
|
||||
() => [
|
||||
{ no: 1, name: "access_tokens", kind: "message", T: UserAccessToken, repeated: true },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.CreateUserAccessTokenRequest
|
||||
*/
|
||||
export const CreateUserAccessTokenRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.CreateUserAccessTokenRequest",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "user_access_token", kind: "message", T: UserAccessToken },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.CreateUserAccessTokenResponse
|
||||
*/
|
||||
export const CreateUserAccessTokenResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.CreateUserAccessTokenResponse",
|
||||
() => [
|
||||
{ no: 1, name: "access_token", kind: "message", T: UserAccessToken },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.DeleteUserAccessTokenRequest
|
||||
*/
|
||||
export const DeleteUserAccessTokenRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.DeleteUserAccessTokenRequest",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "access_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.DeleteUserAccessTokenResponse
|
||||
*/
|
||||
export const DeleteUserAccessTokenResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.DeleteUserAccessTokenResponse",
|
||||
[],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.UserAccessToken
|
||||
*/
|
||||
export const UserAccessToken = proto3.makeMessageType(
|
||||
"slash.api.v2.UserAccessToken",
|
||||
() => [
|
||||
{ no: 1, name: "access_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 3, name: "issued_at", kind: "message", T: Timestamp },
|
||||
{ no: 4, name: "expires_at", kind: "message", T: Timestamp },
|
||||
],
|
||||
);
|
||||
|
25
extension/src/types/proto/store/common_pb.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/common.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.RowStatus
|
||||
*/
|
||||
export declare enum RowStatus {
|
||||
/**
|
||||
* @generated from enum value: ROW_STATUS_UNSPECIFIED = 0;
|
||||
*/
|
||||
ROW_STATUS_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: NORMAL = 1;
|
||||
*/
|
||||
NORMAL = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: ARCHIVED = 2;
|
||||
*/
|
||||
ARCHIVED = 2,
|
||||
}
|
||||
|
19
extension/src/types/proto/store/common_pb.js
Normal file
@ -0,0 +1,19 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/common.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.RowStatus
|
||||
*/
|
||||
export const RowStatus = proto3.makeEnum(
|
||||
"slash.store.RowStatus",
|
||||
[
|
||||
{no: 0, name: "ROW_STATUS_UNSPECIFIED"},
|
||||
{no: 1, name: "NORMAL"},
|
||||
{no: 2, name: "ARCHIVED"},
|
||||
],
|
||||
);
|
||||
|
147
extension/src/types/proto/store/shortcut_pb.d.ts
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/shortcut.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
|
||||
import { Message, proto3 } from "@bufbuild/protobuf";
|
||||
import type { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.Visibility
|
||||
*/
|
||||
export declare enum Visibility {
|
||||
/**
|
||||
* @generated from enum value: VISIBILITY_UNSPECIFIED = 0;
|
||||
*/
|
||||
VISIBILITY_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: PRIVATE = 1;
|
||||
*/
|
||||
PRIVATE = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: WORKSPACE = 2;
|
||||
*/
|
||||
WORKSPACE = 2,
|
||||
|
||||
/**
|
||||
* @generated from enum value: PUBLIC = 3;
|
||||
*/
|
||||
PUBLIC = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.Shortcut
|
||||
*/
|
||||
export declare class Shortcut extends Message<Shortcut> {
|
||||
/**
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @generated from field: int32 creator_id = 2;
|
||||
*/
|
||||
creatorId: number;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 created_ts = 3;
|
||||
*/
|
||||
createdTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 updated_ts = 4;
|
||||
*/
|
||||
updatedTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.store.RowStatus row_status = 5;
|
||||
*/
|
||||
rowStatus: RowStatus;
|
||||
|
||||
/**
|
||||
* @generated from field: string name = 6;
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string link = 7;
|
||||
*/
|
||||
link: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string title = 8;
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* @generated from field: repeated string tags = 9;
|
||||
*/
|
||||
tags: string[];
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 10;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.store.Visibility visibility = 11;
|
||||
*/
|
||||
visibility: Visibility;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.store.OpenGraphMetadata og_metadata = 12;
|
||||
*/
|
||||
ogMetadata?: OpenGraphMetadata;
|
||||
|
||||
constructor(data?: PartialMessage<Shortcut>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.Shortcut";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Shortcut;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Shortcut;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Shortcut;
|
||||
|
||||
static equals(a: Shortcut | PlainMessage<Shortcut> | undefined, b: Shortcut | PlainMessage<Shortcut> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.OpenGraphMetadata
|
||||
*/
|
||||
export declare class OpenGraphMetadata extends Message<OpenGraphMetadata> {
|
||||
/**
|
||||
* @generated from field: string title = 1;
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 2;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string image = 3;
|
||||
*/
|
||||
image: string;
|
||||
|
||||
constructor(data?: PartialMessage<OpenGraphMetadata>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.OpenGraphMetadata";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static equals(a: OpenGraphMetadata | PlainMessage<OpenGraphMetadata> | undefined, b: OpenGraphMetadata | PlainMessage<OpenGraphMetadata> | undefined): boolean;
|
||||
}
|
||||
|
54
extension/src/types/proto/store/shortcut_pb.js
Normal file
@ -0,0 +1,54 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/shortcut.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
import { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.Visibility
|
||||
*/
|
||||
export const Visibility = proto3.makeEnum(
|
||||
"slash.store.Visibility",
|
||||
[
|
||||
{no: 0, name: "VISIBILITY_UNSPECIFIED"},
|
||||
{no: 1, name: "PRIVATE"},
|
||||
{no: 2, name: "WORKSPACE"},
|
||||
{no: 3, name: "PUBLIC"},
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.Shortcut
|
||||
*/
|
||||
export const Shortcut = proto3.makeMessageType(
|
||||
"slash.store.Shortcut",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "creator_id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 3, name: "created_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 4, name: "updated_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 5, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) },
|
||||
{ no: 6, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 7, name: "link", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 8, name: "title", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 9, name: "tags", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
||||
{ no: 10, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 11, name: "visibility", kind: "enum", T: proto3.getEnumType(Visibility) },
|
||||
{ no: 12, name: "og_metadata", kind: "message", T: OpenGraphMetadata },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.OpenGraphMetadata
|
||||
*/
|
||||
export const OpenGraphMetadata = proto3.makeMessageType(
|
||||
"slash.store.OpenGraphMetadata",
|
||||
() => [
|
||||
{ no: 1, name: "title", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 3, name: "image", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
116
extension/src/types/proto/store/user_setting_pb.d.ts
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/user_setting.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
|
||||
import { Message, proto3 } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.UserSettingKey
|
||||
*/
|
||||
export declare enum UserSettingKey {
|
||||
/**
|
||||
* @generated from enum value: USER_SETTING_KEY_UNSPECIFIED = 0;
|
||||
*/
|
||||
USER_SETTING_KEY_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: USER_SETTING_ACCESS_TOKENS = 1;
|
||||
*/
|
||||
USER_SETTING_ACCESS_TOKENS = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.UserSetting
|
||||
*/
|
||||
export declare class UserSetting extends Message<UserSetting> {
|
||||
/**
|
||||
* @generated from field: int32 user_id = 1;
|
||||
*/
|
||||
userId: number;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.store.UserSettingKey key = 2;
|
||||
*/
|
||||
key: UserSettingKey;
|
||||
|
||||
/**
|
||||
* @generated from oneof slash.store.UserSetting.value
|
||||
*/
|
||||
value: {
|
||||
/**
|
||||
* @generated from field: slash.store.AccessTokensUserSetting access_tokens_user_setting = 3;
|
||||
*/
|
||||
value: AccessTokensUserSetting;
|
||||
case: "accessTokensUserSetting";
|
||||
} | { case: undefined; value?: undefined };
|
||||
|
||||
constructor(data?: PartialMessage<UserSetting>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.UserSetting";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UserSetting;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): UserSetting;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): UserSetting;
|
||||
|
||||
static equals(a: UserSetting | PlainMessage<UserSetting> | undefined, b: UserSetting | PlainMessage<UserSetting> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.AccessTokensUserSetting
|
||||
*/
|
||||
export declare class AccessTokensUserSetting extends Message<AccessTokensUserSetting> {
|
||||
/**
|
||||
* @generated from field: repeated slash.store.AccessTokensUserSetting.AccessToken access_tokens = 1;
|
||||
*/
|
||||
accessTokens: AccessTokensUserSetting_AccessToken[];
|
||||
|
||||
constructor(data?: PartialMessage<AccessTokensUserSetting>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.AccessTokensUserSetting";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AccessTokensUserSetting;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AccessTokensUserSetting;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AccessTokensUserSetting;
|
||||
|
||||
static equals(a: AccessTokensUserSetting | PlainMessage<AccessTokensUserSetting> | undefined, b: AccessTokensUserSetting | PlainMessage<AccessTokensUserSetting> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.AccessTokensUserSetting.AccessToken
|
||||
*/
|
||||
export declare class AccessTokensUserSetting_AccessToken extends Message<AccessTokensUserSetting_AccessToken> {
|
||||
/**
|
||||
* @generated from field: string access_token = 1;
|
||||
*/
|
||||
accessToken: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 2;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
constructor(data?: PartialMessage<AccessTokensUserSetting_AccessToken>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.AccessTokensUserSetting.AccessToken";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AccessTokensUserSetting_AccessToken;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AccessTokensUserSetting_AccessToken;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AccessTokensUserSetting_AccessToken;
|
||||
|
||||
static equals(a: AccessTokensUserSetting_AccessToken | PlainMessage<AccessTokensUserSetting_AccessToken> | undefined, b: AccessTokensUserSetting_AccessToken | PlainMessage<AccessTokensUserSetting_AccessToken> | undefined): boolean;
|
||||
}
|
||||
|
52
extension/src/types/proto/store/user_setting_pb.js
Normal file
@ -0,0 +1,52 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/user_setting.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.UserSettingKey
|
||||
*/
|
||||
export const UserSettingKey = proto3.makeEnum(
|
||||
"slash.store.UserSettingKey",
|
||||
[
|
||||
{no: 0, name: "USER_SETTING_KEY_UNSPECIFIED"},
|
||||
{no: 1, name: "USER_SETTING_ACCESS_TOKENS"},
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.UserSetting
|
||||
*/
|
||||
export const UserSetting = proto3.makeMessageType(
|
||||
"slash.store.UserSetting",
|
||||
() => [
|
||||
{ no: 1, name: "user_id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "key", kind: "enum", T: proto3.getEnumType(UserSettingKey) },
|
||||
{ no: 3, name: "access_tokens_user_setting", kind: "message", T: AccessTokensUserSetting, oneof: "value" },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.AccessTokensUserSetting
|
||||
*/
|
||||
export const AccessTokensUserSetting = proto3.makeMessageType(
|
||||
"slash.store.AccessTokensUserSetting",
|
||||
() => [
|
||||
{ no: 1, name: "access_tokens", kind: "message", T: AccessTokensUserSetting_AccessToken, repeated: true },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.AccessTokensUserSetting.AccessToken
|
||||
*/
|
||||
export const AccessTokensUserSetting_AccessToken = proto3.makeMessageType(
|
||||
"slash.store.AccessTokensUserSetting.AccessToken",
|
||||
() => [
|
||||
{ no: 1, name: "access_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
{localName: "AccessTokensUserSetting_AccessToken"},
|
||||
);
|
||||
|
8
extension/tailwind.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
/* eslint-disable no-undef */
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
mode: "jit",
|
||||
darkMode: "class",
|
||||
content: ["./**/*.tsx"],
|
||||
plugins: [],
|
||||
};
|
19
extension/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "plasmo/templates/tsconfig.base",
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"include": [
|
||||
".plasmo/index.d.ts",
|
||||
"./**/*.ts",
|
||||
"./**/*.tsx"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
},
|
||||
"baseUrl": "."
|
||||
}
|
||||
}
|
78
proto/api/v2/shortcut_service.proto
Normal file
@ -0,0 +1,78 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package slash.api.v2;
|
||||
|
||||
import "api/v2/common.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/client.proto";
|
||||
|
||||
option go_package = "gen/api/v2";
|
||||
|
||||
service ShortcutService {
|
||||
rpc ListShortcuts(ListShortcutsRequest) returns (ListShortcutsResponse) {
|
||||
option (google.api.http) = {get: "/api/v2/shortcuts"};
|
||||
}
|
||||
// GetShortcut returns a shortcut by name.
|
||||
rpc GetShortcut(GetShortcutRequest) returns (GetShortcutResponse) {
|
||||
option (google.api.http) = {get: "/api/v2/shortcuts/{name}"};
|
||||
option (google.api.method_signature) = "name";
|
||||
}
|
||||
}
|
||||
|
||||
message Shortcut {
|
||||
int32 id = 1;
|
||||
|
||||
int32 creator_id = 2;
|
||||
|
||||
int64 created_ts = 3;
|
||||
|
||||
int64 updated_ts = 4;
|
||||
|
||||
RowStatus row_status = 5;
|
||||
|
||||
string name = 6;
|
||||
|
||||
string link = 7;
|
||||
|
||||
string title = 8;
|
||||
|
||||
repeated string tags = 9;
|
||||
|
||||
string description = 10;
|
||||
|
||||
Visibility visibility = 11;
|
||||
|
||||
OpenGraphMetadata og_metadata = 12;
|
||||
}
|
||||
|
||||
message OpenGraphMetadata {
|
||||
string title = 1;
|
||||
|
||||
string description = 2;
|
||||
|
||||
string image = 3;
|
||||
}
|
||||
|
||||
enum Visibility {
|
||||
VISIBILITY_UNSPECIFIED = 0;
|
||||
|
||||
PRIVATE = 1;
|
||||
|
||||
WORKSPACE = 2;
|
||||
|
||||
PUBLIC = 3;
|
||||
}
|
||||
|
||||
message ListShortcutsRequest {}
|
||||
|
||||
message ListShortcutsResponse {
|
||||
repeated Shortcut shortcuts = 1;
|
||||
}
|
||||
|
||||
message GetShortcutRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message GetShortcutResponse {
|
||||
Shortcut shortcut = 1;
|
||||
}
|
@ -5,14 +5,34 @@ package slash.api.v2;
|
||||
import "api/v2/common.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/client.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
option go_package = "gen/api/v2";
|
||||
|
||||
service UserService {
|
||||
// GetUser returns a user by id.
|
||||
rpc GetUser(GetUserRequest) returns (GetUserResponse) {
|
||||
option (google.api.http) = {get: "/api/v2/users/{id}"};
|
||||
option (google.api.method_signature) = "id";
|
||||
}
|
||||
// ListUserAccessTokens returns a list of access tokens for a user.
|
||||
rpc ListUserAccessTokens(ListUserAccessTokensRequest) returns (ListUserAccessTokensResponse) {
|
||||
option (google.api.http) = {get: "/api/v2/users/{id}/access_tokens"};
|
||||
option (google.api.method_signature) = "id";
|
||||
}
|
||||
// CreateUserAccessToken creates a new access token for a user.
|
||||
rpc CreateUserAccessToken(CreateUserAccessTokenRequest) returns (CreateUserAccessTokenResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v2/users/{id}/access_tokens"
|
||||
body: "user_access_token"
|
||||
};
|
||||
option (google.api.method_signature) = "id";
|
||||
}
|
||||
// DeleteUserAccessToken deletes an access token for a user.
|
||||
rpc DeleteUserAccessToken(DeleteUserAccessTokenRequest) returns (DeleteUserAccessTokenResponse) {
|
||||
option (google.api.http) = {delete: "/api/v2/users/{id}/access_tokens/{access_token}"};
|
||||
option (google.api.method_signature) = "id,access_token";
|
||||
}
|
||||
}
|
||||
|
||||
message User {
|
||||
@ -46,3 +66,39 @@ message GetUserRequest {
|
||||
message GetUserResponse {
|
||||
User user = 1;
|
||||
}
|
||||
|
||||
message ListUserAccessTokensRequest {
|
||||
// id is the user id.
|
||||
int32 id = 1;
|
||||
}
|
||||
|
||||
message ListUserAccessTokensResponse {
|
||||
repeated UserAccessToken access_tokens = 1;
|
||||
}
|
||||
|
||||
message CreateUserAccessTokenRequest {
|
||||
// id is the user id.
|
||||
int32 id = 1;
|
||||
|
||||
UserAccessToken user_access_token = 2;
|
||||
}
|
||||
|
||||
message CreateUserAccessTokenResponse {
|
||||
UserAccessToken access_token = 1;
|
||||
}
|
||||
|
||||
message DeleteUserAccessTokenRequest {
|
||||
// id is the user id.
|
||||
int32 id = 1;
|
||||
// access_token is the access token to delete.
|
||||
string access_token = 2;
|
||||
}
|
||||
|
||||
message DeleteUserAccessTokenResponse {}
|
||||
|
||||
message UserAccessToken {
|
||||
string access_token = 1;
|
||||
string description = 2;
|
||||
google.protobuf.Timestamp issued_at = 3;
|
||||
google.protobuf.Timestamp expires_at = 4;
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ plugins:
|
||||
out: gen
|
||||
opt:
|
||||
- paths=source_relative
|
||||
# Build the TypeScript definitions for the web and extension.
|
||||
- plugin: buf.build/bufbuild/es:v1.3.0
|
||||
out: ../web/src/types/proto
|
||||
- plugin: buf.build/bufbuild/es:v1.3.0
|
||||
out: ../extension/src/types/proto
|
||||
- plugin: buf.build/community/pseudomuto-doc:v1.5.1
|
||||
out: gen
|
||||
opt:
|
||||
|
@ -6,10 +6,29 @@
|
||||
- [api/v2/common.proto](#api_v2_common-proto)
|
||||
- [RowStatus](#slash-api-v2-RowStatus)
|
||||
|
||||
- [api/v2/shortcut_service.proto](#api_v2_shortcut_service-proto)
|
||||
- [GetShortcutRequest](#slash-api-v2-GetShortcutRequest)
|
||||
- [GetShortcutResponse](#slash-api-v2-GetShortcutResponse)
|
||||
- [ListShortcutsRequest](#slash-api-v2-ListShortcutsRequest)
|
||||
- [ListShortcutsResponse](#slash-api-v2-ListShortcutsResponse)
|
||||
- [OpenGraphMetadata](#slash-api-v2-OpenGraphMetadata)
|
||||
- [Shortcut](#slash-api-v2-Shortcut)
|
||||
|
||||
- [Visibility](#slash-api-v2-Visibility)
|
||||
|
||||
- [ShortcutService](#slash-api-v2-ShortcutService)
|
||||
|
||||
- [api/v2/user_service.proto](#api_v2_user_service-proto)
|
||||
- [CreateUserAccessTokenRequest](#slash-api-v2-CreateUserAccessTokenRequest)
|
||||
- [CreateUserAccessTokenResponse](#slash-api-v2-CreateUserAccessTokenResponse)
|
||||
- [DeleteUserAccessTokenRequest](#slash-api-v2-DeleteUserAccessTokenRequest)
|
||||
- [DeleteUserAccessTokenResponse](#slash-api-v2-DeleteUserAccessTokenResponse)
|
||||
- [GetUserRequest](#slash-api-v2-GetUserRequest)
|
||||
- [GetUserResponse](#slash-api-v2-GetUserResponse)
|
||||
- [ListUserAccessTokensRequest](#slash-api-v2-ListUserAccessTokensRequest)
|
||||
- [ListUserAccessTokensResponse](#slash-api-v2-ListUserAccessTokensResponse)
|
||||
- [User](#slash-api-v2-User)
|
||||
- [UserAccessToken](#slash-api-v2-UserAccessToken)
|
||||
|
||||
- [Role](#slash-api-v2-Role)
|
||||
|
||||
@ -48,6 +67,145 @@
|
||||
|
||||
|
||||
|
||||
<a name="api_v2_shortcut_service-proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## api/v2/shortcut_service.proto
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-GetShortcutRequest"></a>
|
||||
|
||||
### GetShortcutRequest
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| name | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-GetShortcutResponse"></a>
|
||||
|
||||
### GetShortcutResponse
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| shortcut | [Shortcut](#slash-api-v2-Shortcut) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-ListShortcutsRequest"></a>
|
||||
|
||||
### ListShortcutsRequest
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-ListShortcutsResponse"></a>
|
||||
|
||||
### ListShortcutsResponse
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| shortcuts | [Shortcut](#slash-api-v2-Shortcut) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-OpenGraphMetadata"></a>
|
||||
|
||||
### OpenGraphMetadata
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| title | [string](#string) | | |
|
||||
| description | [string](#string) | | |
|
||||
| image | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-Shortcut"></a>
|
||||
|
||||
### Shortcut
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [int32](#int32) | | |
|
||||
| creator_id | [int32](#int32) | | |
|
||||
| created_ts | [int64](#int64) | | |
|
||||
| updated_ts | [int64](#int64) | | |
|
||||
| row_status | [RowStatus](#slash-api-v2-RowStatus) | | |
|
||||
| name | [string](#string) | | |
|
||||
| link | [string](#string) | | |
|
||||
| title | [string](#string) | | |
|
||||
| tags | [string](#string) | repeated | |
|
||||
| description | [string](#string) | | |
|
||||
| visibility | [Visibility](#slash-api-v2-Visibility) | | |
|
||||
| og_metadata | [OpenGraphMetadata](#slash-api-v2-OpenGraphMetadata) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-Visibility"></a>
|
||||
|
||||
### Visibility
|
||||
|
||||
|
||||
| Name | Number | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| VISIBILITY_UNSPECIFIED | 0 | |
|
||||
| PRIVATE | 1 | |
|
||||
| WORKSPACE | 2 | |
|
||||
| PUBLIC | 3 | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-ShortcutService"></a>
|
||||
|
||||
### ShortcutService
|
||||
|
||||
|
||||
| Method Name | Request Type | Response Type | Description |
|
||||
| ----------- | ------------ | ------------- | ------------|
|
||||
| ListShortcuts | [ListShortcutsRequest](#slash-api-v2-ListShortcutsRequest) | [ListShortcutsResponse](#slash-api-v2-ListShortcutsResponse) | |
|
||||
| GetShortcut | [GetShortcutRequest](#slash-api-v2-GetShortcutRequest) | [GetShortcutResponse](#slash-api-v2-GetShortcutResponse) | GetShortcut returns a shortcut by name. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="api_v2_user_service-proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
@ -55,6 +213,63 @@
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-CreateUserAccessTokenRequest"></a>
|
||||
|
||||
### CreateUserAccessTokenRequest
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [int32](#int32) | | id is the user id. |
|
||||
| user_access_token | [UserAccessToken](#slash-api-v2-UserAccessToken) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-CreateUserAccessTokenResponse"></a>
|
||||
|
||||
### CreateUserAccessTokenResponse
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| access_token | [UserAccessToken](#slash-api-v2-UserAccessToken) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-DeleteUserAccessTokenRequest"></a>
|
||||
|
||||
### DeleteUserAccessTokenRequest
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [int32](#int32) | | id is the user id. |
|
||||
| access_token | [string](#string) | | access_token is the access token to delete. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-DeleteUserAccessTokenResponse"></a>
|
||||
|
||||
### DeleteUserAccessTokenResponse
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-GetUserRequest"></a>
|
||||
|
||||
### GetUserRequest
|
||||
@ -85,6 +300,36 @@
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-ListUserAccessTokensRequest"></a>
|
||||
|
||||
### ListUserAccessTokensRequest
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| id | [int32](#int32) | | id is the user id. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-ListUserAccessTokensResponse"></a>
|
||||
|
||||
### ListUserAccessTokensResponse
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| access_tokens | [UserAccessToken](#slash-api-v2-UserAccessToken) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-User"></a>
|
||||
|
||||
### User
|
||||
@ -106,6 +351,24 @@
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-UserAccessToken"></a>
|
||||
|
||||
### UserAccessToken
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| access_token | [string](#string) | | |
|
||||
| description | [string](#string) | | |
|
||||
| issued_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | |
|
||||
| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-api-v2-Role"></a>
|
||||
@ -132,7 +395,10 @@
|
||||
|
||||
| Method Name | Request Type | Response Type | Description |
|
||||
| ----------- | ------------ | ------------- | ------------|
|
||||
| GetUser | [GetUserRequest](#slash-api-v2-GetUserRequest) | [GetUserResponse](#slash-api-v2-GetUserResponse) | |
|
||||
| GetUser | [GetUserRequest](#slash-api-v2-GetUserRequest) | [GetUserResponse](#slash-api-v2-GetUserResponse) | GetUser returns a user by id. |
|
||||
| ListUserAccessTokens | [ListUserAccessTokensRequest](#slash-api-v2-ListUserAccessTokensRequest) | [ListUserAccessTokensResponse](#slash-api-v2-ListUserAccessTokensResponse) | ListUserAccessTokens returns a list of access tokens for a user. |
|
||||
| CreateUserAccessToken | [CreateUserAccessTokenRequest](#slash-api-v2-CreateUserAccessTokenRequest) | [CreateUserAccessTokenResponse](#slash-api-v2-CreateUserAccessTokenResponse) | CreateUserAccessToken creates a new access token for a user. |
|
||||
| DeleteUserAccessToken | [DeleteUserAccessTokenRequest](#slash-api-v2-DeleteUserAccessTokenRequest) | [DeleteUserAccessTokenResponse](#slash-api-v2-DeleteUserAccessTokenResponse) | DeleteUserAccessToken deletes an access token for a user. |
|
||||
|
||||
|
||||
|
||||
|
685
proto/gen/api/v2/shortcut_service.pb.go
Normal file
@ -0,0 +1,685 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc (unknown)
|
||||
// source: api/v2/shortcut_service.proto
|
||||
|
||||
package apiv2
|
||||
|
||||
import (
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Visibility int32
|
||||
|
||||
const (
|
||||
Visibility_VISIBILITY_UNSPECIFIED Visibility = 0
|
||||
Visibility_PRIVATE Visibility = 1
|
||||
Visibility_WORKSPACE Visibility = 2
|
||||
Visibility_PUBLIC Visibility = 3
|
||||
)
|
||||
|
||||
// Enum value maps for Visibility.
|
||||
var (
|
||||
Visibility_name = map[int32]string{
|
||||
0: "VISIBILITY_UNSPECIFIED",
|
||||
1: "PRIVATE",
|
||||
2: "WORKSPACE",
|
||||
3: "PUBLIC",
|
||||
}
|
||||
Visibility_value = map[string]int32{
|
||||
"VISIBILITY_UNSPECIFIED": 0,
|
||||
"PRIVATE": 1,
|
||||
"WORKSPACE": 2,
|
||||
"PUBLIC": 3,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Visibility) Enum() *Visibility {
|
||||
p := new(Visibility)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Visibility) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Visibility) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_api_v2_shortcut_service_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (Visibility) Type() protoreflect.EnumType {
|
||||
return &file_api_v2_shortcut_service_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x Visibility) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Visibility.Descriptor instead.
|
||||
func (Visibility) EnumDescriptor() ([]byte, []int) {
|
||||
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type Shortcut struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
CreatorId int32 `protobuf:"varint,2,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"`
|
||||
CreatedTs int64 `protobuf:"varint,3,opt,name=created_ts,json=createdTs,proto3" json:"created_ts,omitempty"`
|
||||
UpdatedTs int64 `protobuf:"varint,4,opt,name=updated_ts,json=updatedTs,proto3" json:"updated_ts,omitempty"`
|
||||
RowStatus RowStatus `protobuf:"varint,5,opt,name=row_status,json=rowStatus,proto3,enum=slash.api.v2.RowStatus" json:"row_status,omitempty"`
|
||||
Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Link string `protobuf:"bytes,7,opt,name=link,proto3" json:"link,omitempty"`
|
||||
Title string `protobuf:"bytes,8,opt,name=title,proto3" json:"title,omitempty"`
|
||||
Tags []string `protobuf:"bytes,9,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||
Description string `protobuf:"bytes,10,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Visibility Visibility `protobuf:"varint,11,opt,name=visibility,proto3,enum=slash.api.v2.Visibility" json:"visibility,omitempty"`
|
||||
OgMetadata *OpenGraphMetadata `protobuf:"bytes,12,opt,name=og_metadata,json=ogMetadata,proto3" json:"og_metadata,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Shortcut) Reset() {
|
||||
*x = Shortcut{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Shortcut) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Shortcut) ProtoMessage() {}
|
||||
|
||||
func (x *Shortcut) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Shortcut.ProtoReflect.Descriptor instead.
|
||||
func (*Shortcut) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetId() int32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetCreatorId() int32 {
|
||||
if x != nil {
|
||||
return x.CreatorId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetCreatedTs() int64 {
|
||||
if x != nil {
|
||||
return x.CreatedTs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetUpdatedTs() int64 {
|
||||
if x != nil {
|
||||
return x.UpdatedTs
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetRowStatus() RowStatus {
|
||||
if x != nil {
|
||||
return x.RowStatus
|
||||
}
|
||||
return RowStatus_ROW_STATUS_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetLink() string {
|
||||
if x != nil {
|
||||
return x.Link
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetTitle() string {
|
||||
if x != nil {
|
||||
return x.Title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetTags() []string {
|
||||
if x != nil {
|
||||
return x.Tags
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetVisibility() Visibility {
|
||||
if x != nil {
|
||||
return x.Visibility
|
||||
}
|
||||
return Visibility_VISIBILITY_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *Shortcut) GetOgMetadata() *OpenGraphMetadata {
|
||||
if x != nil {
|
||||
return x.OgMetadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type OpenGraphMetadata struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
|
||||
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Image string `protobuf:"bytes,3,opt,name=image,proto3" json:"image,omitempty"`
|
||||
}
|
||||
|
||||
func (x *OpenGraphMetadata) Reset() {
|
||||
*x = OpenGraphMetadata{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *OpenGraphMetadata) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*OpenGraphMetadata) ProtoMessage() {}
|
||||
|
||||
func (x *OpenGraphMetadata) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use OpenGraphMetadata.ProtoReflect.Descriptor instead.
|
||||
func (*OpenGraphMetadata) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *OpenGraphMetadata) GetTitle() string {
|
||||
if x != nil {
|
||||
return x.Title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *OpenGraphMetadata) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *OpenGraphMetadata) GetImage() string {
|
||||
if x != nil {
|
||||
return x.Image
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ListShortcutsRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *ListShortcutsRequest) Reset() {
|
||||
*x = ListShortcutsRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListShortcutsRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListShortcutsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListShortcutsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListShortcutsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListShortcutsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type ListShortcutsResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Shortcuts []*Shortcut `protobuf:"bytes,1,rep,name=shortcuts,proto3" json:"shortcuts,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ListShortcutsResponse) Reset() {
|
||||
*x = ListShortcutsResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListShortcutsResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListShortcutsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListShortcutsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListShortcutsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListShortcutsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ListShortcutsResponse) GetShortcuts() []*Shortcut {
|
||||
if x != nil {
|
||||
return x.Shortcuts
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetShortcutRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetShortcutRequest) Reset() {
|
||||
*x = GetShortcutRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetShortcutRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetShortcutRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetShortcutRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetShortcutRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetShortcutRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *GetShortcutRequest) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetShortcutResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Shortcut *Shortcut `protobuf:"bytes,1,opt,name=shortcut,proto3" json:"shortcut,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetShortcutResponse) Reset() {
|
||||
*x = GetShortcutResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetShortcutResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetShortcutResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetShortcutResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_shortcut_service_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetShortcutResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetShortcutResponse) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *GetShortcutResponse) GetShortcut() *Shortcut {
|
||||
if x != nil {
|
||||
return x.Shortcut
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_api_v2_shortcut_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_api_v2_shortcut_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x1d, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75,
|
||||
0x74, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
|
||||
0x0c, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x13, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61,
|
||||
0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9f, 0x03, 0x0a, 0x08, 0x53, 0x68,
|
||||
0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f,
|
||||
0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61,
|
||||
0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
|
||||
0x5f, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x64, 0x54, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f,
|
||||
0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x64, 0x54, 0x73, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x52, 0x09, 0x72, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c,
|
||||
0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67,
|
||||
0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x38, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x0b, 0x20,
|
||||
0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76,
|
||||
0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x40, 0x0a, 0x0b, 0x6f, 0x67, 0x5f,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,
|
||||
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x70,
|
||||
0x65, 0x6e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52,
|
||||
0x0a, 0x6f, 0x67, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x61, 0x0a, 0x11, 0x4f,
|
||||
0x70, 0x65, 0x6e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
|
||||
0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67,
|
||||
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x16,
|
||||
0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4d, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x68,
|
||||
0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x34, 0x0a, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72,
|
||||
0x74, 0x63, 0x75, 0x74, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72,
|
||||
0x74, 0x63, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22,
|
||||
0x49, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63,
|
||||
0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74,
|
||||
0x52, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x2a, 0x50, 0x0a, 0x0a, 0x56, 0x69,
|
||||
0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x49, 0x53, 0x49,
|
||||
0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
|
||||
0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10,
|
||||
0x01, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x10, 0x02,
|
||||
0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x03, 0x32, 0x83, 0x02, 0x0a,
|
||||
0x0f, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x12, 0x73, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74,
|
||||
0x73, 0x12, 0x22, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70,
|
||||
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75,
|
||||
0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x68, 0x6f, 0x72,
|
||||
0x74, 0x63, 0x75, 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72,
|
||||
0x74, 0x63, 0x75, 0x74, 0x12, 0x20, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0xda, 0x41, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76,
|
||||
0x32, 0x2f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x7d, 0x42, 0xab, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x14, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75,
|
||||
0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a,
|
||||
0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
|
||||
0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32,
|
||||
0xa2, 0x02, 0x03, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41,
|
||||
0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70,
|
||||
0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69,
|
||||
0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
|
||||
0x02, 0x0e, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_api_v2_shortcut_service_proto_rawDescOnce sync.Once
|
||||
file_api_v2_shortcut_service_proto_rawDescData = file_api_v2_shortcut_service_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_api_v2_shortcut_service_proto_rawDescGZIP() []byte {
|
||||
file_api_v2_shortcut_service_proto_rawDescOnce.Do(func() {
|
||||
file_api_v2_shortcut_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_shortcut_service_proto_rawDescData)
|
||||
})
|
||||
return file_api_v2_shortcut_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_api_v2_shortcut_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_api_v2_shortcut_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_api_v2_shortcut_service_proto_goTypes = []interface{}{
|
||||
(Visibility)(0), // 0: slash.api.v2.Visibility
|
||||
(*Shortcut)(nil), // 1: slash.api.v2.Shortcut
|
||||
(*OpenGraphMetadata)(nil), // 2: slash.api.v2.OpenGraphMetadata
|
||||
(*ListShortcutsRequest)(nil), // 3: slash.api.v2.ListShortcutsRequest
|
||||
(*ListShortcutsResponse)(nil), // 4: slash.api.v2.ListShortcutsResponse
|
||||
(*GetShortcutRequest)(nil), // 5: slash.api.v2.GetShortcutRequest
|
||||
(*GetShortcutResponse)(nil), // 6: slash.api.v2.GetShortcutResponse
|
||||
(RowStatus)(0), // 7: slash.api.v2.RowStatus
|
||||
}
|
||||
var file_api_v2_shortcut_service_proto_depIdxs = []int32{
|
||||
7, // 0: slash.api.v2.Shortcut.row_status:type_name -> slash.api.v2.RowStatus
|
||||
0, // 1: slash.api.v2.Shortcut.visibility:type_name -> slash.api.v2.Visibility
|
||||
2, // 2: slash.api.v2.Shortcut.og_metadata:type_name -> slash.api.v2.OpenGraphMetadata
|
||||
1, // 3: slash.api.v2.ListShortcutsResponse.shortcuts:type_name -> slash.api.v2.Shortcut
|
||||
1, // 4: slash.api.v2.GetShortcutResponse.shortcut:type_name -> slash.api.v2.Shortcut
|
||||
3, // 5: slash.api.v2.ShortcutService.ListShortcuts:input_type -> slash.api.v2.ListShortcutsRequest
|
||||
5, // 6: slash.api.v2.ShortcutService.GetShortcut:input_type -> slash.api.v2.GetShortcutRequest
|
||||
4, // 7: slash.api.v2.ShortcutService.ListShortcuts:output_type -> slash.api.v2.ListShortcutsResponse
|
||||
6, // 8: slash.api.v2.ShortcutService.GetShortcut:output_type -> slash.api.v2.GetShortcutResponse
|
||||
7, // [7:9] is the sub-list for method output_type
|
||||
5, // [5:7] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
5, // [5:5] is the sub-list for extension extendee
|
||||
0, // [0:5] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_api_v2_shortcut_service_proto_init() }
|
||||
func file_api_v2_shortcut_service_proto_init() {
|
||||
if File_api_v2_shortcut_service_proto != nil {
|
||||
return
|
||||
}
|
||||
file_api_v2_common_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_api_v2_shortcut_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Shortcut); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_shortcut_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*OpenGraphMetadata); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_shortcut_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListShortcutsRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_shortcut_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListShortcutsResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_shortcut_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetShortcutRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_shortcut_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetShortcutResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_api_v2_shortcut_service_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_api_v2_shortcut_service_proto_goTypes,
|
||||
DependencyIndexes: file_api_v2_shortcut_service_proto_depIdxs,
|
||||
EnumInfos: file_api_v2_shortcut_service_proto_enumTypes,
|
||||
MessageInfos: file_api_v2_shortcut_service_proto_msgTypes,
|
||||
}.Build()
|
||||
File_api_v2_shortcut_service_proto = out.File
|
||||
file_api_v2_shortcut_service_proto_rawDesc = nil
|
||||
file_api_v2_shortcut_service_proto_goTypes = nil
|
||||
file_api_v2_shortcut_service_proto_depIdxs = nil
|
||||
}
|
258
proto/gen/api/v2/shortcut_service.pb.gw.go
Normal file
@ -0,0 +1,258 @@
|
||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: api/v2/shortcut_service.proto
|
||||
|
||||
/*
|
||||
Package apiv2 is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package apiv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
var _ = metadata.Join
|
||||
|
||||
func request_ShortcutService_ListShortcuts_0(ctx context.Context, marshaler runtime.Marshaler, client ShortcutServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListShortcutsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.ListShortcuts(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_ShortcutService_ListShortcuts_0(ctx context.Context, marshaler runtime.Marshaler, server ShortcutServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListShortcutsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.ListShortcuts(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_ShortcutService_GetShortcut_0(ctx context.Context, marshaler runtime.Marshaler, client ShortcutServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetShortcutRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
|
||||
protoReq.Name, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetShortcut(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_ShortcutService_GetShortcut_0(ctx context.Context, marshaler runtime.Marshaler, server ShortcutServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq GetShortcutRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["name"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
||||
}
|
||||
|
||||
protoReq.Name, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetShortcut(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterShortcutServiceHandlerServer registers the http handlers for service ShortcutService to "mux".
|
||||
// UnaryRPC :call ShortcutServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterShortcutServiceHandlerFromEndpoint instead.
|
||||
func RegisterShortcutServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ShortcutServiceServer) error {
|
||||
|
||||
mux.Handle("GET", pattern_ShortcutService_ListShortcuts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/slash.api.v2.ShortcutService/ListShortcuts", runtime.WithHTTPPathPattern("/api/v2/shortcuts"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_ShortcutService_ListShortcuts_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ShortcutService_ListShortcuts_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_ShortcutService_GetShortcut_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/slash.api.v2.ShortcutService/GetShortcut", runtime.WithHTTPPathPattern("/api/v2/shortcuts/{name}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_ShortcutService_GetShortcut_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ShortcutService_GetShortcut_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterShortcutServiceHandlerFromEndpoint is same as RegisterShortcutServiceHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterShortcutServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.DialContext(ctx, endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterShortcutServiceHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterShortcutServiceHandler registers the http handlers for service ShortcutService to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterShortcutServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterShortcutServiceHandlerClient(ctx, mux, NewShortcutServiceClient(conn))
|
||||
}
|
||||
|
||||
// RegisterShortcutServiceHandlerClient registers the http handlers for service ShortcutService
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ShortcutServiceClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ShortcutServiceClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "ShortcutServiceClient" to call the correct interceptors.
|
||||
func RegisterShortcutServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ShortcutServiceClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_ShortcutService_ListShortcuts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/slash.api.v2.ShortcutService/ListShortcuts", runtime.WithHTTPPathPattern("/api/v2/shortcuts"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_ShortcutService_ListShortcuts_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ShortcutService_ListShortcuts_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_ShortcutService_GetShortcut_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/slash.api.v2.ShortcutService/GetShortcut", runtime.WithHTTPPathPattern("/api/v2/shortcuts/{name}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_ShortcutService_GetShortcut_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ShortcutService_GetShortcut_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_ShortcutService_ListShortcuts_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "shortcuts"}, ""))
|
||||
|
||||
pattern_ShortcutService_GetShortcut_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "shortcuts", "name"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_ShortcutService_ListShortcuts_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_ShortcutService_GetShortcut_0 = runtime.ForwardResponseMessage
|
||||
)
|
148
proto/gen/api/v2/shortcut_service_grpc.pb.go
Normal file
@ -0,0 +1,148 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc (unknown)
|
||||
// source: api/v2/shortcut_service.proto
|
||||
|
||||
package apiv2
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
ShortcutService_ListShortcuts_FullMethodName = "/slash.api.v2.ShortcutService/ListShortcuts"
|
||||
ShortcutService_GetShortcut_FullMethodName = "/slash.api.v2.ShortcutService/GetShortcut"
|
||||
)
|
||||
|
||||
// ShortcutServiceClient is the client API for ShortcutService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type ShortcutServiceClient interface {
|
||||
ListShortcuts(ctx context.Context, in *ListShortcutsRequest, opts ...grpc.CallOption) (*ListShortcutsResponse, error)
|
||||
// GetShortcut returns a shortcut by name.
|
||||
GetShortcut(ctx context.Context, in *GetShortcutRequest, opts ...grpc.CallOption) (*GetShortcutResponse, error)
|
||||
}
|
||||
|
||||
type shortcutServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewShortcutServiceClient(cc grpc.ClientConnInterface) ShortcutServiceClient {
|
||||
return &shortcutServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *shortcutServiceClient) ListShortcuts(ctx context.Context, in *ListShortcutsRequest, opts ...grpc.CallOption) (*ListShortcutsResponse, error) {
|
||||
out := new(ListShortcutsResponse)
|
||||
err := c.cc.Invoke(ctx, ShortcutService_ListShortcuts_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *shortcutServiceClient) GetShortcut(ctx context.Context, in *GetShortcutRequest, opts ...grpc.CallOption) (*GetShortcutResponse, error) {
|
||||
out := new(GetShortcutResponse)
|
||||
err := c.cc.Invoke(ctx, ShortcutService_GetShortcut_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ShortcutServiceServer is the server API for ShortcutService service.
|
||||
// All implementations must embed UnimplementedShortcutServiceServer
|
||||
// for forward compatibility
|
||||
type ShortcutServiceServer interface {
|
||||
ListShortcuts(context.Context, *ListShortcutsRequest) (*ListShortcutsResponse, error)
|
||||
// GetShortcut returns a shortcut by name.
|
||||
GetShortcut(context.Context, *GetShortcutRequest) (*GetShortcutResponse, error)
|
||||
mustEmbedUnimplementedShortcutServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedShortcutServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedShortcutServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedShortcutServiceServer) ListShortcuts(context.Context, *ListShortcutsRequest) (*ListShortcutsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListShortcuts not implemented")
|
||||
}
|
||||
func (UnimplementedShortcutServiceServer) GetShortcut(context.Context, *GetShortcutRequest) (*GetShortcutResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetShortcut not implemented")
|
||||
}
|
||||
func (UnimplementedShortcutServiceServer) mustEmbedUnimplementedShortcutServiceServer() {}
|
||||
|
||||
// UnsafeShortcutServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ShortcutServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeShortcutServiceServer interface {
|
||||
mustEmbedUnimplementedShortcutServiceServer()
|
||||
}
|
||||
|
||||
func RegisterShortcutServiceServer(s grpc.ServiceRegistrar, srv ShortcutServiceServer) {
|
||||
s.RegisterService(&ShortcutService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _ShortcutService_ListShortcuts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListShortcutsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ShortcutServiceServer).ListShortcuts(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ShortcutService_ListShortcuts_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ShortcutServiceServer).ListShortcuts(ctx, req.(*ListShortcutsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ShortcutService_GetShortcut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetShortcutRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ShortcutServiceServer).GetShortcut(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ShortcutService_GetShortcut_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ShortcutServiceServer).GetShortcut(ctx, req.(*GetShortcutRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ShortcutService_ServiceDesc is the grpc.ServiceDesc for ShortcutService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var ShortcutService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "slash.api.v2.ShortcutService",
|
||||
HandlerType: (*ShortcutServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ListShortcuts",
|
||||
Handler: _ShortcutService_ListShortcuts_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetShortcut",
|
||||
Handler: _ShortcutService_GetShortcut_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api/v2/shortcut_service.proto",
|
||||
}
|
@ -10,6 +10,7 @@ import (
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
@ -259,6 +260,370 @@ func (x *GetUserResponse) GetUser() *User {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListUserAccessTokensRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// id is the user id.
|
||||
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ListUserAccessTokensRequest) Reset() {
|
||||
*x = ListUserAccessTokensRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListUserAccessTokensRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListUserAccessTokensRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListUserAccessTokensRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListUserAccessTokensRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListUserAccessTokensRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_user_service_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *ListUserAccessTokensRequest) GetId() int32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ListUserAccessTokensResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
AccessTokens []*UserAccessToken `protobuf:"bytes,1,rep,name=access_tokens,json=accessTokens,proto3" json:"access_tokens,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ListUserAccessTokensResponse) Reset() {
|
||||
*x = ListUserAccessTokensResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListUserAccessTokensResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListUserAccessTokensResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListUserAccessTokensResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListUserAccessTokensResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListUserAccessTokensResponse) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_user_service_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *ListUserAccessTokensResponse) GetAccessTokens() []*UserAccessToken {
|
||||
if x != nil {
|
||||
return x.AccessTokens
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreateUserAccessTokenRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// id is the user id.
|
||||
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
UserAccessToken *UserAccessToken `protobuf:"bytes,2,opt,name=user_access_token,json=userAccessToken,proto3" json:"user_access_token,omitempty"`
|
||||
}
|
||||
|
||||
func (x *CreateUserAccessTokenRequest) Reset() {
|
||||
*x = CreateUserAccessTokenRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *CreateUserAccessTokenRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreateUserAccessTokenRequest) ProtoMessage() {}
|
||||
|
||||
func (x *CreateUserAccessTokenRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CreateUserAccessTokenRequest.ProtoReflect.Descriptor instead.
|
||||
func (*CreateUserAccessTokenRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_user_service_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *CreateUserAccessTokenRequest) GetId() int32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *CreateUserAccessTokenRequest) GetUserAccessToken() *UserAccessToken {
|
||||
if x != nil {
|
||||
return x.UserAccessToken
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreateUserAccessTokenResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
AccessToken *UserAccessToken `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
|
||||
}
|
||||
|
||||
func (x *CreateUserAccessTokenResponse) Reset() {
|
||||
*x = CreateUserAccessTokenResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *CreateUserAccessTokenResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CreateUserAccessTokenResponse) ProtoMessage() {}
|
||||
|
||||
func (x *CreateUserAccessTokenResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CreateUserAccessTokenResponse.ProtoReflect.Descriptor instead.
|
||||
func (*CreateUserAccessTokenResponse) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_user_service_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *CreateUserAccessTokenResponse) GetAccessToken() *UserAccessToken {
|
||||
if x != nil {
|
||||
return x.AccessToken
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DeleteUserAccessTokenRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// id is the user id.
|
||||
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
// access_token is the access token to delete.
|
||||
AccessToken string `protobuf:"bytes,2,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DeleteUserAccessTokenRequest) Reset() {
|
||||
*x = DeleteUserAccessTokenRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteUserAccessTokenRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteUserAccessTokenRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteUserAccessTokenRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteUserAccessTokenRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteUserAccessTokenRequest) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_user_service_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
func (x *DeleteUserAccessTokenRequest) GetId() int32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *DeleteUserAccessTokenRequest) GetAccessToken() string {
|
||||
if x != nil {
|
||||
return x.AccessToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DeleteUserAccessTokenResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *DeleteUserAccessTokenResponse) Reset() {
|
||||
*x = DeleteUserAccessTokenResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *DeleteUserAccessTokenResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteUserAccessTokenResponse) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteUserAccessTokenResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteUserAccessTokenResponse.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteUserAccessTokenResponse) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_user_service_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
type UserAccessToken struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
|
||||
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
|
||||
IssuedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=issued_at,json=issuedAt,proto3" json:"issued_at,omitempty"`
|
||||
ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"`
|
||||
}
|
||||
|
||||
func (x *UserAccessToken) Reset() {
|
||||
*x = UserAccessToken{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *UserAccessToken) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UserAccessToken) ProtoMessage() {}
|
||||
|
||||
func (x *UserAccessToken) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_api_v2_user_service_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UserAccessToken.ProtoReflect.Descriptor instead.
|
||||
func (*UserAccessToken) Descriptor() ([]byte, []int) {
|
||||
return file_api_v2_user_service_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *UserAccessToken) GetAccessToken() string {
|
||||
if x != nil {
|
||||
return x.AccessToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *UserAccessToken) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *UserAccessToken) GetIssuedAt() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.IssuedAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *UserAccessToken) GetExpiresAt() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.ExpiresAt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_api_v2_user_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_api_v2_user_service_proto_rawDesc = []byte{
|
||||
@ -269,49 +634,127 @@ var file_api_v2_user_service_proto_rawDesc = []byte{
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e,
|
||||
0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36,
|
||||
0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0e, 0x32, 0x17, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x72, 0x6f, 0x77,
|
||||
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x64, 0x5f, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x64, 0x54, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
|
||||
0x5f, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x64, 0x54, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x0e, 0x32, 0x12, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61,
|
||||
0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x20,
|
||||
0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64,
|
||||
0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x2a, 0x31, 0x0a, 0x04, 0x52,
|
||||
0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50,
|
||||
0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x4d,
|
||||
0x49, 0x4e, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x02, 0x32, 0x76,
|
||||
0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x67, 0x0a,
|
||||
0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72,
|
||||
0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xa7, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73,
|
||||
0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x55, 0x73, 0x65,
|
||||
0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
|
||||
0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a,
|
||||
0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
|
||||
0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32,
|
||||
0xa2, 0x02, 0x03, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41,
|
||||
0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70,
|
||||
0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69,
|
||||
0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
|
||||
0x02, 0x0e, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12,
|
||||
0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x72, 0x6f,
|
||||
0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x64, 0x5f, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x64, 0x54, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x64, 0x5f, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x64, 0x54, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d,
|
||||
0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x22,
|
||||
0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69,
|
||||
0x64, 0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2d, 0x0a, 0x1b,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x62, 0x0a, 0x1c, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x61,
|
||||
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22,
|
||||
0x79, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12,
|
||||
0x49, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6c, 0x61,
|
||||
0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63,
|
||||
0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x41,
|
||||
0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x61, 0x0a, 0x1d, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x61,
|
||||
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x51, 0x0a,
|
||||
0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73,
|
||||
0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a,
|
||||
0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63,
|
||||
0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0xca, 0x01, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f,
|
||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
|
||||
0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
|
||||
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x09, 0x69, 0x73,
|
||||
0x73, 0x75, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x69, 0x73, 0x73, 0x75, 0x65,
|
||||
0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61,
|
||||
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x2a, 0x31,
|
||||
0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55,
|
||||
0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05,
|
||||
0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10,
|
||||
0x02, 0x32, 0x88, 0x05, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||
0x65, 0x12, 0x67, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x73,
|
||||
0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55,
|
||||
0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x6c, 0x61,
|
||||
0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
|
||||
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xda, 0x41, 0x02, 0x69, 0x64,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f,
|
||||
0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9c, 0x01, 0x0a, 0x14, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73,
|
||||
0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a,
|
||||
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0xda, 0x41, 0x02, 0x69,
|
||||
0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
|
||||
0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x63, 0x63, 0x65,
|
||||
0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x15, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||
0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x2b, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0xda, 0x41,
|
||||
0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x3a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f,
|
||||
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x20, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d,
|
||||
0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xbb,
|
||||
0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73,
|
||||
0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63,
|
||||
0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x49, 0xda, 0x41, 0x0f, 0x69, 0x64, 0x2c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f,
|
||||
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x2a, 0x2f, 0x2f, 0x61, 0x70,
|
||||
0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f,
|
||||
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x2f, 0x7b, 0x61,
|
||||
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x7d, 0x42, 0xa7, 0x01, 0x0a,
|
||||
0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
|
||||
0x32, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
|
||||
0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53,
|
||||
0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c,
|
||||
0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61,
|
||||
0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41,
|
||||
0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -327,25 +770,44 @@ func file_api_v2_user_service_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_api_v2_user_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_api_v2_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_api_v2_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
|
||||
var file_api_v2_user_service_proto_goTypes = []interface{}{
|
||||
(Role)(0), // 0: slash.api.v2.Role
|
||||
(*User)(nil), // 1: slash.api.v2.User
|
||||
(*GetUserRequest)(nil), // 2: slash.api.v2.GetUserRequest
|
||||
(*GetUserResponse)(nil), // 3: slash.api.v2.GetUserResponse
|
||||
(RowStatus)(0), // 4: slash.api.v2.RowStatus
|
||||
(*ListUserAccessTokensRequest)(nil), // 4: slash.api.v2.ListUserAccessTokensRequest
|
||||
(*ListUserAccessTokensResponse)(nil), // 5: slash.api.v2.ListUserAccessTokensResponse
|
||||
(*CreateUserAccessTokenRequest)(nil), // 6: slash.api.v2.CreateUserAccessTokenRequest
|
||||
(*CreateUserAccessTokenResponse)(nil), // 7: slash.api.v2.CreateUserAccessTokenResponse
|
||||
(*DeleteUserAccessTokenRequest)(nil), // 8: slash.api.v2.DeleteUserAccessTokenRequest
|
||||
(*DeleteUserAccessTokenResponse)(nil), // 9: slash.api.v2.DeleteUserAccessTokenResponse
|
||||
(*UserAccessToken)(nil), // 10: slash.api.v2.UserAccessToken
|
||||
(RowStatus)(0), // 11: slash.api.v2.RowStatus
|
||||
(*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp
|
||||
}
|
||||
var file_api_v2_user_service_proto_depIdxs = []int32{
|
||||
4, // 0: slash.api.v2.User.row_status:type_name -> slash.api.v2.RowStatus
|
||||
11, // 0: slash.api.v2.User.row_status:type_name -> slash.api.v2.RowStatus
|
||||
0, // 1: slash.api.v2.User.role:type_name -> slash.api.v2.Role
|
||||
1, // 2: slash.api.v2.GetUserResponse.user:type_name -> slash.api.v2.User
|
||||
2, // 3: slash.api.v2.UserService.GetUser:input_type -> slash.api.v2.GetUserRequest
|
||||
3, // 4: slash.api.v2.UserService.GetUser:output_type -> slash.api.v2.GetUserResponse
|
||||
4, // [4:5] is the sub-list for method output_type
|
||||
3, // [3:4] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
10, // 3: slash.api.v2.ListUserAccessTokensResponse.access_tokens:type_name -> slash.api.v2.UserAccessToken
|
||||
10, // 4: slash.api.v2.CreateUserAccessTokenRequest.user_access_token:type_name -> slash.api.v2.UserAccessToken
|
||||
10, // 5: slash.api.v2.CreateUserAccessTokenResponse.access_token:type_name -> slash.api.v2.UserAccessToken
|
||||
12, // 6: slash.api.v2.UserAccessToken.issued_at:type_name -> google.protobuf.Timestamp
|
||||
12, // 7: slash.api.v2.UserAccessToken.expires_at:type_name -> google.protobuf.Timestamp
|
||||
2, // 8: slash.api.v2.UserService.GetUser:input_type -> slash.api.v2.GetUserRequest
|
||||
4, // 9: slash.api.v2.UserService.ListUserAccessTokens:input_type -> slash.api.v2.ListUserAccessTokensRequest
|
||||
6, // 10: slash.api.v2.UserService.CreateUserAccessToken:input_type -> slash.api.v2.CreateUserAccessTokenRequest
|
||||
8, // 11: slash.api.v2.UserService.DeleteUserAccessToken:input_type -> slash.api.v2.DeleteUserAccessTokenRequest
|
||||
3, // 12: slash.api.v2.UserService.GetUser:output_type -> slash.api.v2.GetUserResponse
|
||||
5, // 13: slash.api.v2.UserService.ListUserAccessTokens:output_type -> slash.api.v2.ListUserAccessTokensResponse
|
||||
7, // 14: slash.api.v2.UserService.CreateUserAccessToken:output_type -> slash.api.v2.CreateUserAccessTokenResponse
|
||||
9, // 15: slash.api.v2.UserService.DeleteUserAccessToken:output_type -> slash.api.v2.DeleteUserAccessTokenResponse
|
||||
12, // [12:16] is the sub-list for method output_type
|
||||
8, // [8:12] is the sub-list for method input_type
|
||||
8, // [8:8] is the sub-list for extension type_name
|
||||
8, // [8:8] is the sub-list for extension extendee
|
||||
0, // [0:8] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_api_v2_user_service_proto_init() }
|
||||
@ -391,6 +853,90 @@ func file_api_v2_user_service_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_user_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListUserAccessTokensRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_user_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListUserAccessTokensResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_user_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*CreateUserAccessTokenRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_user_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*CreateUserAccessTokenResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_user_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteUserAccessTokenRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_user_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*DeleteUserAccessTokenResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_api_v2_user_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UserAccessToken); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@ -398,7 +944,7 @@ func file_api_v2_user_service_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_api_v2_user_service_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 3,
|
||||
NumMessages: 10,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
@ -83,6 +83,198 @@ func local_request_UserService_GetUser_0(ctx context.Context, marshaler runtime.
|
||||
|
||||
}
|
||||
|
||||
func request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListUserAccessTokensRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.ListUserAccessTokens(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListUserAccessTokensRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.ListUserAccessTokens(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_UserService_CreateUserAccessToken_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq CreateUserAccessTokenRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.UserAccessToken); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.CreateUserAccessToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_CreateUserAccessToken_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq CreateUserAccessTokenRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.UserAccessToken); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.CreateUserAccessToken(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_UserService_DeleteUserAccessToken_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeleteUserAccessTokenRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["access_token"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "access_token")
|
||||
}
|
||||
|
||||
protoReq.AccessToken, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "access_token", err)
|
||||
}
|
||||
|
||||
msg, err := client.DeleteUserAccessToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_UserService_DeleteUserAccessToken_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq DeleteUserAccessTokenRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.Int32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["access_token"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "access_token")
|
||||
}
|
||||
|
||||
protoReq.AccessToken, err = runtime.String(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "access_token", err)
|
||||
}
|
||||
|
||||
msg, err := server.DeleteUserAccessToken(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterUserServiceHandlerServer registers the http handlers for service UserService to "mux".
|
||||
// UnaryRPC :call UserServiceServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
@ -114,6 +306,81 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_UserService_ListUserAccessTokens_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/slash.api.v2.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v2/users/{id}/access_tokens"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_ListUserAccessTokens_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_ListUserAccessTokens_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_UserService_CreateUserAccessToken_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/slash.api.v2.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/users/{id}/access_tokens"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_CreateUserAccessToken_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_CreateUserAccessToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_UserService_DeleteUserAccessToken_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/slash.api.v2.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/users/{id}/access_tokens/{access_token}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_UserService_DeleteUserAccessToken_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_DeleteUserAccessToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -177,13 +444,91 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_UserService_ListUserAccessTokens_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/slash.api.v2.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v2/users/{id}/access_tokens"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_ListUserAccessTokens_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_ListUserAccessTokens_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_UserService_CreateUserAccessToken_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/slash.api.v2.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/users/{id}/access_tokens"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_CreateUserAccessToken_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_CreateUserAccessToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("DELETE", pattern_UserService_DeleteUserAccessToken_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/slash.api.v2.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/users/{id}/access_tokens/{access_token}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_UserService_DeleteUserAccessToken_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_UserService_DeleteUserAccessToken_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "users", "id"}, ""))
|
||||
|
||||
pattern_UserService_ListUserAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "users", "id", "access_tokens"}, ""))
|
||||
|
||||
pattern_UserService_CreateUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "users", "id", "access_tokens"}, ""))
|
||||
|
||||
pattern_UserService_DeleteUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v2", "users", "id", "access_tokens", "access_token"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_UserService_GetUser_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_UserService_ListUserAccessTokens_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_UserService_CreateUserAccessToken_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_UserService_DeleteUserAccessToken_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
@ -20,13 +20,23 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
UserService_GetUser_FullMethodName = "/slash.api.v2.UserService/GetUser"
|
||||
UserService_ListUserAccessTokens_FullMethodName = "/slash.api.v2.UserService/ListUserAccessTokens"
|
||||
UserService_CreateUserAccessToken_FullMethodName = "/slash.api.v2.UserService/CreateUserAccessToken"
|
||||
UserService_DeleteUserAccessToken_FullMethodName = "/slash.api.v2.UserService/DeleteUserAccessToken"
|
||||
)
|
||||
|
||||
// UserServiceClient is the client API for UserService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type UserServiceClient interface {
|
||||
// GetUser returns a user by id.
|
||||
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error)
|
||||
// ListUserAccessTokens returns a list of access tokens for a user.
|
||||
ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error)
|
||||
// CreateUserAccessToken creates a new access token for a user.
|
||||
CreateUserAccessToken(ctx context.Context, in *CreateUserAccessTokenRequest, opts ...grpc.CallOption) (*CreateUserAccessTokenResponse, error)
|
||||
// DeleteUserAccessToken deletes an access token for a user.
|
||||
DeleteUserAccessToken(ctx context.Context, in *DeleteUserAccessTokenRequest, opts ...grpc.CallOption) (*DeleteUserAccessTokenResponse, error)
|
||||
}
|
||||
|
||||
type userServiceClient struct {
|
||||
@ -46,11 +56,45 @@ func (c *userServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opt
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error) {
|
||||
out := new(ListUserAccessTokensResponse)
|
||||
err := c.cc.Invoke(ctx, UserService_ListUserAccessTokens_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) CreateUserAccessToken(ctx context.Context, in *CreateUserAccessTokenRequest, opts ...grpc.CallOption) (*CreateUserAccessTokenResponse, error) {
|
||||
out := new(CreateUserAccessTokenResponse)
|
||||
err := c.cc.Invoke(ctx, UserService_CreateUserAccessToken_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *userServiceClient) DeleteUserAccessToken(ctx context.Context, in *DeleteUserAccessTokenRequest, opts ...grpc.CallOption) (*DeleteUserAccessTokenResponse, error) {
|
||||
out := new(DeleteUserAccessTokenResponse)
|
||||
err := c.cc.Invoke(ctx, UserService_DeleteUserAccessToken_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// UserServiceServer is the server API for UserService service.
|
||||
// All implementations must embed UnimplementedUserServiceServer
|
||||
// for forward compatibility
|
||||
type UserServiceServer interface {
|
||||
// GetUser returns a user by id.
|
||||
GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error)
|
||||
// ListUserAccessTokens returns a list of access tokens for a user.
|
||||
ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error)
|
||||
// CreateUserAccessToken creates a new access token for a user.
|
||||
CreateUserAccessToken(context.Context, *CreateUserAccessTokenRequest) (*CreateUserAccessTokenResponse, error)
|
||||
// DeleteUserAccessToken deletes an access token for a user.
|
||||
DeleteUserAccessToken(context.Context, *DeleteUserAccessTokenRequest) (*DeleteUserAccessTokenResponse, error)
|
||||
mustEmbedUnimplementedUserServiceServer()
|
||||
}
|
||||
|
||||
@ -61,6 +105,15 @@ type UnimplementedUserServiceServer struct {
|
||||
func (UnimplementedUserServiceServer) GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListUserAccessTokens not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) CreateUserAccessToken(context.Context, *CreateUserAccessTokenRequest) (*CreateUserAccessTokenResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateUserAccessToken not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) DeleteUserAccessToken(context.Context, *DeleteUserAccessTokenRequest) (*DeleteUserAccessTokenResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteUserAccessToken not implemented")
|
||||
}
|
||||
func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {}
|
||||
|
||||
// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
@ -92,6 +145,60 @@ func _UserService_GetUser_Handler(srv interface{}, ctx context.Context, dec func
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_ListUserAccessTokens_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListUserAccessTokensRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).ListUserAccessTokens(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: UserService_ListUserAccessTokens_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).ListUserAccessTokens(ctx, req.(*ListUserAccessTokensRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_CreateUserAccessToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateUserAccessTokenRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).CreateUserAccessToken(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: UserService_CreateUserAccessToken_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).CreateUserAccessToken(ctx, req.(*CreateUserAccessTokenRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _UserService_DeleteUserAccessToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteUserAccessTokenRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(UserServiceServer).DeleteUserAccessToken(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: UserService_DeleteUserAccessToken_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(UserServiceServer).DeleteUserAccessToken(ctx, req.(*DeleteUserAccessTokenRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@ -103,6 +210,18 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GetUser",
|
||||
Handler: _UserService_GetUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListUserAccessTokens",
|
||||
Handler: _UserService_ListUserAccessTokens_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateUserAccessToken",
|
||||
Handler: _UserService_CreateUserAccessToken_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteUserAccessToken",
|
||||
Handler: _UserService_DeleteUserAccessToken_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "api/v2/user_service.proto",
|
||||
|
@ -12,6 +12,13 @@
|
||||
|
||||
- [Visibility](#slash-store-Visibility)
|
||||
|
||||
- [store/user_setting.proto](#store_user_setting-proto)
|
||||
- [AccessTokensUserSetting](#slash-store-AccessTokensUserSetting)
|
||||
- [AccessTokensUserSetting.AccessToken](#slash-store-AccessTokensUserSetting-AccessToken)
|
||||
- [UserSetting](#slash-store-UserSetting)
|
||||
|
||||
- [UserSettingKey](#slash-store-UserSettingKey)
|
||||
|
||||
- [Scalar Value Types](#scalar-value-types)
|
||||
|
||||
|
||||
@ -118,6 +125,82 @@
|
||||
|
||||
|
||||
|
||||
<a name="store_user_setting-proto"></a>
|
||||
<p align="right"><a href="#top">Top</a></p>
|
||||
|
||||
## store/user_setting.proto
|
||||
|
||||
|
||||
|
||||
<a name="slash-store-AccessTokensUserSetting"></a>
|
||||
|
||||
### AccessTokensUserSetting
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| access_tokens | [AccessTokensUserSetting.AccessToken](#slash-store-AccessTokensUserSetting-AccessToken) | repeated | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-store-AccessTokensUserSetting-AccessToken"></a>
|
||||
|
||||
### AccessTokensUserSetting.AccessToken
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| access_token | [string](#string) | | |
|
||||
| description | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-store-UserSetting"></a>
|
||||
|
||||
### UserSetting
|
||||
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| user_id | [int32](#int32) | | |
|
||||
| key | [UserSettingKey](#slash-store-UserSettingKey) | | |
|
||||
| access_tokens_user_setting | [AccessTokensUserSetting](#slash-store-AccessTokensUserSetting) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="slash-store-UserSettingKey"></a>
|
||||
|
||||
### UserSettingKey
|
||||
|
||||
|
||||
| Name | Number | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| USER_SETTING_KEY_UNSPECIFIED | 0 | |
|
||||
| USER_SETTING_ACCESS_TOKENS | 1 | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Scalar Value Types
|
||||
|
||||
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
|
||||
|
398
proto/gen/store/user_setting.pb.go
Normal file
@ -0,0 +1,398 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.31.0
|
||||
// protoc (unknown)
|
||||
// source: store/user_setting.proto
|
||||
|
||||
package store
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type UserSettingKey int32
|
||||
|
||||
const (
|
||||
UserSettingKey_USER_SETTING_KEY_UNSPECIFIED UserSettingKey = 0
|
||||
UserSettingKey_USER_SETTING_ACCESS_TOKENS UserSettingKey = 1
|
||||
)
|
||||
|
||||
// Enum value maps for UserSettingKey.
|
||||
var (
|
||||
UserSettingKey_name = map[int32]string{
|
||||
0: "USER_SETTING_KEY_UNSPECIFIED",
|
||||
1: "USER_SETTING_ACCESS_TOKENS",
|
||||
}
|
||||
UserSettingKey_value = map[string]int32{
|
||||
"USER_SETTING_KEY_UNSPECIFIED": 0,
|
||||
"USER_SETTING_ACCESS_TOKENS": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x UserSettingKey) Enum() *UserSettingKey {
|
||||
p := new(UserSettingKey)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x UserSettingKey) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (UserSettingKey) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_store_user_setting_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (UserSettingKey) Type() protoreflect.EnumType {
|
||||
return &file_store_user_setting_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x UserSettingKey) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UserSettingKey.Descriptor instead.
|
||||
func (UserSettingKey) EnumDescriptor() ([]byte, []int) {
|
||||
return file_store_user_setting_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type UserSetting struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
UserId int32 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
Key UserSettingKey `protobuf:"varint,2,opt,name=key,proto3,enum=slash.store.UserSettingKey" json:"key,omitempty"`
|
||||
// Types that are assignable to Value:
|
||||
//
|
||||
// *UserSetting_AccessTokensUserSetting
|
||||
Value isUserSetting_Value `protobuf_oneof:"value"`
|
||||
}
|
||||
|
||||
func (x *UserSetting) Reset() {
|
||||
*x = UserSetting{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_store_user_setting_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *UserSetting) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UserSetting) ProtoMessage() {}
|
||||
|
||||
func (x *UserSetting) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_store_user_setting_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UserSetting.ProtoReflect.Descriptor instead.
|
||||
func (*UserSetting) Descriptor() ([]byte, []int) {
|
||||
return file_store_user_setting_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *UserSetting) GetUserId() int32 {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UserSetting) GetKey() UserSettingKey {
|
||||
if x != nil {
|
||||
return x.Key
|
||||
}
|
||||
return UserSettingKey_USER_SETTING_KEY_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (m *UserSetting) GetValue() isUserSetting_Value {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *UserSetting) GetAccessTokensUserSetting() *AccessTokensUserSetting {
|
||||
if x, ok := x.GetValue().(*UserSetting_AccessTokensUserSetting); ok {
|
||||
return x.AccessTokensUserSetting
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isUserSetting_Value interface {
|
||||
isUserSetting_Value()
|
||||
}
|
||||
|
||||
type UserSetting_AccessTokensUserSetting struct {
|
||||
AccessTokensUserSetting *AccessTokensUserSetting `protobuf:"bytes,3,opt,name=access_tokens_user_setting,json=accessTokensUserSetting,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*UserSetting_AccessTokensUserSetting) isUserSetting_Value() {}
|
||||
|
||||
type AccessTokensUserSetting struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
AccessTokens []*AccessTokensUserSetting_AccessToken `protobuf:"bytes,1,rep,name=access_tokens,json=accessTokens,proto3" json:"access_tokens,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AccessTokensUserSetting) Reset() {
|
||||
*x = AccessTokensUserSetting{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_store_user_setting_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AccessTokensUserSetting) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AccessTokensUserSetting) ProtoMessage() {}
|
||||
|
||||
func (x *AccessTokensUserSetting) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_store_user_setting_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AccessTokensUserSetting.ProtoReflect.Descriptor instead.
|
||||
func (*AccessTokensUserSetting) Descriptor() ([]byte, []int) {
|
||||
return file_store_user_setting_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *AccessTokensUserSetting) GetAccessTokens() []*AccessTokensUserSetting_AccessToken {
|
||||
if x != nil {
|
||||
return x.AccessTokens
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AccessTokensUserSetting_AccessToken struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
|
||||
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AccessTokensUserSetting_AccessToken) Reset() {
|
||||
*x = AccessTokensUserSetting_AccessToken{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_store_user_setting_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *AccessTokensUserSetting_AccessToken) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AccessTokensUserSetting_AccessToken) ProtoMessage() {}
|
||||
|
||||
func (x *AccessTokensUserSetting_AccessToken) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_store_user_setting_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AccessTokensUserSetting_AccessToken.ProtoReflect.Descriptor instead.
|
||||
func (*AccessTokensUserSetting_AccessToken) Descriptor() ([]byte, []int) {
|
||||
return file_store_user_setting_proto_rawDescGZIP(), []int{1, 0}
|
||||
}
|
||||
|
||||
func (x *AccessTokensUserSetting_AccessToken) GetAccessToken() string {
|
||||
if x != nil {
|
||||
return x.AccessToken
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AccessTokensUserSetting_AccessToken) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_store_user_setting_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_store_user_setting_proto_rawDesc = []byte{
|
||||
0x0a, 0x18, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74,
|
||||
0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x73, 0x6c, 0x61, 0x73,
|
||||
0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72,
|
||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64,
|
||||
0x12, 0x2d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e,
|
||||
0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72,
|
||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
|
||||
0x63, 0x0a, 0x1a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
|
||||
0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x55, 0x73,
|
||||
0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x17, 0x61, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74,
|
||||
0x74, 0x69, 0x6e, 0x67, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc4, 0x01,
|
||||
0x0a, 0x17, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x55, 0x73,
|
||||
0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x55, 0x0a, 0x0d, 0x61, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x30, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41,
|
||||
0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x55, 0x73, 0x65, 0x72, 0x53,
|
||||
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
|
||||
0x1a, 0x52, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x52, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74,
|
||||
0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x1c, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53,
|
||||
0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
|
||||
0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x53, 0x45, 0x52,
|
||||
0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f,
|
||||
0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x53, 0x10, 0x01, 0x42, 0x9a, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d,
|
||||
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x10, 0x55, 0x73,
|
||||
0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
|
||||
0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f,
|
||||
0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x53, 0x53, 0x58,
|
||||
0xaa, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02,
|
||||
0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x53,
|
||||
0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
|
||||
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_store_user_setting_proto_rawDescOnce sync.Once
|
||||
file_store_user_setting_proto_rawDescData = file_store_user_setting_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_store_user_setting_proto_rawDescGZIP() []byte {
|
||||
file_store_user_setting_proto_rawDescOnce.Do(func() {
|
||||
file_store_user_setting_proto_rawDescData = protoimpl.X.CompressGZIP(file_store_user_setting_proto_rawDescData)
|
||||
})
|
||||
return file_store_user_setting_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_store_user_setting_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_store_user_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_store_user_setting_proto_goTypes = []interface{}{
|
||||
(UserSettingKey)(0), // 0: slash.store.UserSettingKey
|
||||
(*UserSetting)(nil), // 1: slash.store.UserSetting
|
||||
(*AccessTokensUserSetting)(nil), // 2: slash.store.AccessTokensUserSetting
|
||||
(*AccessTokensUserSetting_AccessToken)(nil), // 3: slash.store.AccessTokensUserSetting.AccessToken
|
||||
}
|
||||
var file_store_user_setting_proto_depIdxs = []int32{
|
||||
0, // 0: slash.store.UserSetting.key:type_name -> slash.store.UserSettingKey
|
||||
2, // 1: slash.store.UserSetting.access_tokens_user_setting:type_name -> slash.store.AccessTokensUserSetting
|
||||
3, // 2: slash.store.AccessTokensUserSetting.access_tokens:type_name -> slash.store.AccessTokensUserSetting.AccessToken
|
||||
3, // [3:3] is the sub-list for method output_type
|
||||
3, // [3:3] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_store_user_setting_proto_init() }
|
||||
func file_store_user_setting_proto_init() {
|
||||
if File_store_user_setting_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_store_user_setting_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UserSetting); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_store_user_setting_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AccessTokensUserSetting); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_store_user_setting_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AccessTokensUserSetting_AccessToken); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_store_user_setting_proto_msgTypes[0].OneofWrappers = []interface{}{
|
||||
(*UserSetting_AccessTokensUserSetting)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_store_user_setting_proto_rawDesc,
|
||||
NumEnums: 1,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_store_user_setting_proto_goTypes,
|
||||
DependencyIndexes: file_store_user_setting_proto_depIdxs,
|
||||
EnumInfos: file_store_user_setting_proto_enumTypes,
|
||||
MessageInfos: file_store_user_setting_proto_msgTypes,
|
||||
}.Build()
|
||||
File_store_user_setting_proto = out.File
|
||||
file_store_user_setting_proto_rawDesc = nil
|
||||
file_store_user_setting_proto_goTypes = nil
|
||||
file_store_user_setting_proto_depIdxs = nil
|
||||
}
|
29
proto/store/user_setting.proto
Normal file
@ -0,0 +1,29 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package slash.store;
|
||||
|
||||
option go_package = "gen/store";
|
||||
|
||||
message UserSetting {
|
||||
int32 user_id = 1;
|
||||
|
||||
UserSettingKey key = 2;
|
||||
|
||||
oneof value {
|
||||
AccessTokensUserSetting access_tokens_user_setting = 3;
|
||||
}
|
||||
}
|
||||
|
||||
enum UserSettingKey {
|
||||
USER_SETTING_KEY_UNSPECIFIED = 0;
|
||||
|
||||
USER_SETTING_ACCESS_TOKENS = 1;
|
||||
}
|
||||
|
||||
message AccessTokensUserSetting {
|
||||
message AccessToken {
|
||||
string access_token = 1;
|
||||
string description = 2;
|
||||
}
|
||||
repeated AccessToken access_tokens = 1;
|
||||
}
|
@ -5,7 +5,7 @@ tmp_dir = ".air"
|
||||
bin = "./.air/slash --mode dev"
|
||||
cmd = "go build -o ./.air/slash ./cmd/slash/main.go"
|
||||
delay = 1000
|
||||
exclude_dir = [".air", "web", "build"]
|
||||
exclude_dir = [".air", "web", "extension", "build"]
|
||||
exclude_file = []
|
||||
exclude_regex = []
|
||||
exclude_unchanged = false
|
||||
|
@ -9,10 +9,10 @@ import (
|
||||
|
||||
// Version is the service current released version.
|
||||
// Semantic versioning: https://semver.org/
|
||||
var Version = "0.4.0"
|
||||
var Version = "0.4.1"
|
||||
|
||||
// DevVersion is the service current development version.
|
||||
var DevVersion = "0.4.0"
|
||||
var DevVersion = "0.4.1"
|
||||
|
||||
func GetCurrentVersion(mode string) string {
|
||||
if mode == "dev" || mode == "demo" {
|
||||
|
@ -3,21 +3,19 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type UserSetting struct {
|
||||
UserID int32
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
)
|
||||
|
||||
type FindUserSetting struct {
|
||||
UserID *int32
|
||||
Key string
|
||||
Key storepb.UserSettingKey
|
||||
}
|
||||
|
||||
func (s *Store) UpsertUserSetting(ctx context.Context, upsert *UserSetting) (*UserSetting, error) {
|
||||
func (s *Store) UpsertUserSetting(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) {
|
||||
stmt := `
|
||||
INSERT INTO user_setting (
|
||||
user_id, key, value
|
||||
@ -26,20 +24,31 @@ func (s *Store) UpsertUserSetting(ctx context.Context, upsert *UserSetting) (*Us
|
||||
ON CONFLICT(user_id, key) DO UPDATE
|
||||
SET value = EXCLUDED.value
|
||||
`
|
||||
if _, err := s.db.ExecContext(ctx, stmt, upsert.UserID, upsert.Key, upsert.Value); err != nil {
|
||||
var valueString string
|
||||
if upsert.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS {
|
||||
valueBytes, err := protojson.Marshal(upsert.GetAccessTokensUserSetting())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valueString = string(valueBytes)
|
||||
} else {
|
||||
return nil, errors.New("invalid user setting key")
|
||||
}
|
||||
|
||||
if _, err := s.db.ExecContext(ctx, stmt, upsert.UserId, upsert.Key.String(), valueString); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userSettingMessage := upsert
|
||||
s.userSettingCache.Store(getUserSettingCacheKey(userSettingMessage.UserID, userSettingMessage.Key), userSettingMessage)
|
||||
s.userSettingCache.Store(getUserSettingCacheKey(userSettingMessage.UserId, userSettingMessage.Key.String()), userSettingMessage)
|
||||
return userSettingMessage, nil
|
||||
}
|
||||
|
||||
func (s *Store) ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*UserSetting, error) {
|
||||
func (s *Store) ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*storepb.UserSetting, error) {
|
||||
where, args := []string{"1 = 1"}, []any{}
|
||||
|
||||
if v := find.Key; v != "" {
|
||||
where, args = append(where, "key = ?"), append(args, v)
|
||||
if v := find.Key; v != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED {
|
||||
where, args = append(where, "key = ?"), append(args, v.String())
|
||||
}
|
||||
if v := find.UserID; v != nil {
|
||||
where, args = append(where, "user_id = ?"), append(args, *find.UserID)
|
||||
@ -58,16 +67,27 @@ func (s *Store) ListUserSettings(ctx context.Context, find *FindUserSetting) ([]
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
userSettingList := make([]*UserSetting, 0)
|
||||
userSettingList := make([]*storepb.UserSetting, 0)
|
||||
for rows.Next() {
|
||||
userSetting := &UserSetting{}
|
||||
userSetting := &storepb.UserSetting{}
|
||||
var keyString, valueString string
|
||||
if err := rows.Scan(
|
||||
&userSetting.UserID,
|
||||
&userSetting.Key,
|
||||
&userSetting.Value,
|
||||
&userSetting.UserId,
|
||||
&keyString,
|
||||
&valueString,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userSetting.Key = storepb.UserSettingKey(storepb.UserSettingKey_value[keyString])
|
||||
if userSetting.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS {
|
||||
accessTokensUserSetting := &storepb.AccessTokensUserSetting{}
|
||||
if err := protojson.Unmarshal([]byte(valueString), accessTokensUserSetting); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
userSetting.Value = &storepb.UserSetting_AccessTokensUserSetting{
|
||||
AccessTokensUserSetting: accessTokensUserSetting,
|
||||
}
|
||||
}
|
||||
userSettingList = append(userSettingList, userSetting)
|
||||
}
|
||||
|
||||
@ -76,15 +96,15 @@ func (s *Store) ListUserSettings(ctx context.Context, find *FindUserSetting) ([]
|
||||
}
|
||||
|
||||
for _, userSetting := range userSettingList {
|
||||
s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserID, userSetting.Key), userSetting)
|
||||
s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserId, userSetting.Key.String()), userSetting)
|
||||
}
|
||||
return userSettingList, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetUserSetting(ctx context.Context, find *FindUserSetting) (*UserSetting, error) {
|
||||
if find.UserID != nil && find.Key != "" {
|
||||
if cache, ok := s.userSettingCache.Load(getUserSettingCacheKey(*find.UserID, find.Key)); ok {
|
||||
return cache.(*UserSetting), nil
|
||||
func (s *Store) GetUserSetting(ctx context.Context, find *FindUserSetting) (*storepb.UserSetting, error) {
|
||||
if find.UserID != nil && find.Key != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED {
|
||||
if cache, ok := s.userSettingCache.Load(getUserSettingCacheKey(*find.UserID, find.Key.String())); ok {
|
||||
return cache.(*storepb.UserSetting), nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,9 +117,9 @@ func (s *Store) GetUserSetting(ctx context.Context, find *FindUserSetting) (*Use
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
userSettingMessage := list[0]
|
||||
s.userSettingCache.Store(getUserSettingCacheKey(userSettingMessage.UserID, userSettingMessage.Key), userSettingMessage)
|
||||
return userSettingMessage, nil
|
||||
userSetting := list[0]
|
||||
s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserId, userSetting.Key.String()), userSetting)
|
||||
return userSetting, nil
|
||||
}
|
||||
|
||||
func vacuumUserSetting(ctx context.Context, tx *sql.Tx) error {
|
||||
@ -120,3 +140,20 @@ func vacuumUserSetting(ctx context.Context, tx *sql.Tx) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUserAccessTokens returns the access tokens of the user.
|
||||
func (s *Store) GetUserAccessTokens(ctx context.Context, userID int32) ([]*storepb.AccessTokensUserSetting_AccessToken, error) {
|
||||
userSetting, err := s.GetUserSetting(ctx, &FindUserSetting{
|
||||
UserID: &userID,
|
||||
Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userSetting == nil {
|
||||
return []*storepb.AccessTokensUserSetting_AccessToken{}, nil
|
||||
}
|
||||
|
||||
accessTokensUserSetting := userSetting.GetAccessTokensUserSetting()
|
||||
return accessTokensUserSetting.AccessTokens, nil
|
||||
}
|
||||
|
73
test/store/user_setting_test.go
Normal file
@ -0,0 +1,73 @@
|
||||
package teststore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"github.com/boojack/slash/store"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUserSettingStore(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ts := NewTestingStore(ctx, t)
|
||||
user, err := createTestingAdminUser(ctx, ts)
|
||||
require.NoError(t, err)
|
||||
userSettings, err := ts.ListUserSettings(ctx, &store.FindUserSetting{
|
||||
UserID: &user.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(userSettings))
|
||||
accessTokensUserSetting, err := ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
||||
UserId: user.ID,
|
||||
Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
|
||||
Value: &storepb.UserSetting_AccessTokensUserSetting{
|
||||
AccessTokensUserSetting: &storepb.AccessTokensUserSetting{
|
||||
AccessTokens: []*storepb.AccessTokensUserSetting_AccessToken{
|
||||
{
|
||||
AccessToken: "test_access_token",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, accessTokensUserSetting)
|
||||
require.Equal(t, storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS, accessTokensUserSetting.Key)
|
||||
require.Equal(t, user.ID, accessTokensUserSetting.UserId)
|
||||
require.Equal(t, 1, len(accessTokensUserSetting.GetAccessTokensUserSetting().AccessTokens))
|
||||
userSettings, err = ts.ListUserSettings(ctx, &store.FindUserSetting{
|
||||
UserID: &user.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(userSettings))
|
||||
require.Equal(t, accessTokensUserSetting, userSettings[0])
|
||||
accessTokensUserSetting, err = ts.GetUserSetting(ctx, &store.FindUserSetting{
|
||||
UserID: &user.ID,
|
||||
Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, accessTokensUserSetting)
|
||||
require.Equal(t, 1, len(accessTokensUserSetting.GetAccessTokensUserSetting().AccessTokens))
|
||||
require.Equal(t, "test_access_token", accessTokensUserSetting.GetAccessTokensUserSetting().AccessTokens[0].AccessToken)
|
||||
accessTokensUserSetting, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{
|
||||
UserId: user.ID,
|
||||
Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
|
||||
Value: &storepb.UserSetting_AccessTokensUserSetting{
|
||||
AccessTokensUserSetting: &storepb.AccessTokensUserSetting{
|
||||
AccessTokens: []*storepb.AccessTokensUserSetting_AccessToken{
|
||||
{
|
||||
AccessToken: "test_access_token",
|
||||
},
|
||||
{
|
||||
AccessToken: "test_access_token2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, accessTokensUserSetting)
|
||||
require.Equal(t, 2, len(accessTokensUserSetting.GetAccessTokensUserSetting().AccessTokens))
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"printWidth": 140,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"plugins": ["@ianvs/prettier-plugin-sort-imports"],
|
||||
"importOrder": ["<BUILTIN_MODULES>", "<THIRD_PARTY_MODULES>", "^@/(.*)$", "^[./]", ".less$"]
|
||||
}
|
8
web/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
printWidth: 140,
|
||||
useTabs: false,
|
||||
semi: true,
|
||||
singleQuote: false,
|
||||
plugins: [require.resolve("@trivago/prettier-plugin-sort-imports")],
|
||||
importOrder: ["<BUILTIN_MODULES>", "<THIRD_PARTY_MODULES>", "^@/((?!less).+)", "^[./]", "^(.+).less"],
|
||||
};
|
@ -8,6 +8,7 @@
|
||||
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bufbuild/protobuf": "^1.3.0",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/joy": "5.0.0-beta.0",
|
||||
@ -30,7 +31,7 @@
|
||||
"zustand": "^4.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.1.0",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.1.0",
|
||||
"@types/lodash-es": "^4.17.5",
|
||||
"@types/node": "^20.3.1",
|
||||
"@types/react": "^18.2.18",
|
||||
@ -44,8 +45,8 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.27.1",
|
||||
"postcss": "^8.4.21",
|
||||
"prettier": "2.5.1",
|
||||
"prettier": "2.6.2",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.2.1"
|
||||
"vite": "^4.2.3"
|
||||
}
|
||||
}
|
||||
|
212
web/pnpm-lock.yaml
generated
@ -5,6 +5,9 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@bufbuild/protobuf':
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.2.18)(react@18.2.0)
|
||||
@ -67,9 +70,9 @@ dependencies:
|
||||
version: 4.3.8(react@18.2.0)
|
||||
|
||||
devDependencies:
|
||||
'@ianvs/prettier-plugin-sort-imports':
|
||||
'@trivago/prettier-plugin-sort-imports':
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0(prettier@2.5.1)
|
||||
version: 4.1.0(prettier@2.6.2)
|
||||
'@types/lodash-es':
|
||||
specifier: ^4.17.5
|
||||
version: 4.17.5
|
||||
@ -90,7 +93,7 @@ devDependencies:
|
||||
version: 6.2.0(eslint@8.46.0)(typescript@5.0.4)
|
||||
'@vitejs/plugin-react-swc':
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(vite@4.2.1)
|
||||
version: 3.0.0(vite@4.2.3)
|
||||
autoprefixer:
|
||||
specifier: ^10.4.2
|
||||
version: 10.4.2(postcss@8.4.21)
|
||||
@ -102,7 +105,7 @@ devDependencies:
|
||||
version: 8.3.0(eslint@8.46.0)
|
||||
eslint-plugin-prettier:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0(eslint-config-prettier@8.3.0)(eslint@8.46.0)(prettier@2.5.1)
|
||||
version: 4.0.0(eslint-config-prettier@8.3.0)(eslint@8.46.0)(prettier@2.6.2)
|
||||
eslint-plugin-react:
|
||||
specifier: ^7.27.1
|
||||
version: 7.27.1(eslint@8.46.0)
|
||||
@ -110,14 +113,14 @@ devDependencies:
|
||||
specifier: ^8.4.21
|
||||
version: 8.4.21
|
||||
prettier:
|
||||
specifier: 2.5.1
|
||||
version: 2.5.1
|
||||
specifier: 2.6.2
|
||||
version: 2.6.2
|
||||
typescript:
|
||||
specifier: ^5.0.4
|
||||
version: 5.0.4
|
||||
vite:
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1(@types/node@20.3.1)
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3(@types/node@20.3.1)
|
||||
|
||||
packages:
|
||||
|
||||
@ -131,46 +134,19 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/@ampproject/remapping@2.2.1:
|
||||
resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.3
|
||||
'@jridgewell/trace-mapping': 0.3.18
|
||||
dev: true
|
||||
|
||||
/@babel/code-frame@7.22.5:
|
||||
resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/highlight': 7.22.5
|
||||
|
||||
/@babel/compat-data@7.22.9:
|
||||
resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/core@7.22.9:
|
||||
resolution: {integrity: sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==}
|
||||
/@babel/generator@7.17.7:
|
||||
resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.2.1
|
||||
'@babel/code-frame': 7.22.5
|
||||
'@babel/generator': 7.22.9
|
||||
'@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9)
|
||||
'@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9)
|
||||
'@babel/helpers': 7.22.6
|
||||
'@babel/parser': 7.22.7
|
||||
'@babel/template': 7.22.5
|
||||
'@babel/traverse': 7.22.8
|
||||
'@babel/types': 7.22.5
|
||||
convert-source-map: 1.9.0
|
||||
debug: 4.3.4
|
||||
gensync: 1.0.0-beta.2
|
||||
json5: 2.2.3
|
||||
semver: 6.3.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
jsesc: 2.5.2
|
||||
source-map: 0.5.7
|
||||
dev: true
|
||||
|
||||
/@babel/generator@7.22.9:
|
||||
@ -183,20 +159,6 @@ packages:
|
||||
jsesc: 2.5.2
|
||||
dev: true
|
||||
|
||||
/@babel/helper-compilation-targets@7.22.9(@babel/core@7.22.9):
|
||||
resolution: {integrity: sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
dependencies:
|
||||
'@babel/compat-data': 7.22.9
|
||||
'@babel/core': 7.22.9
|
||||
'@babel/helper-validator-option': 7.22.5
|
||||
browserslist: 4.21.10
|
||||
lru-cache: 5.1.1
|
||||
semver: 6.3.1
|
||||
dev: true
|
||||
|
||||
/@babel/helper-environment-visitor@7.22.5:
|
||||
resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@ -222,27 +184,7 @@ packages:
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.22.5
|
||||
|
||||
/@babel/helper-module-transforms@7.22.9(@babel/core@7.22.9):
|
||||
resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
dependencies:
|
||||
'@babel/core': 7.22.9
|
||||
'@babel/helper-environment-visitor': 7.22.5
|
||||
'@babel/helper-module-imports': 7.22.5
|
||||
'@babel/helper-simple-access': 7.22.5
|
||||
'@babel/helper-split-export-declaration': 7.22.6
|
||||
'@babel/helper-validator-identifier': 7.22.5
|
||||
dev: true
|
||||
|
||||
/@babel/helper-simple-access@7.22.5:
|
||||
resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/types': 7.22.5
|
||||
dev: true
|
||||
dev: false
|
||||
|
||||
/@babel/helper-split-export-declaration@7.22.6:
|
||||
resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
|
||||
@ -259,22 +201,6 @@ packages:
|
||||
resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
/@babel/helper-validator-option@7.22.5:
|
||||
resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/helpers@7.22.6:
|
||||
resolution: {integrity: sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/template': 7.22.5
|
||||
'@babel/traverse': 7.22.8
|
||||
'@babel/types': 7.22.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@babel/highlight@7.22.5:
|
||||
resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@ -307,8 +233,8 @@ packages:
|
||||
'@babel/types': 7.22.5
|
||||
dev: true
|
||||
|
||||
/@babel/traverse@7.22.8:
|
||||
resolution: {integrity: sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==}
|
||||
/@babel/traverse@7.17.3:
|
||||
resolution: {integrity: sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.22.5
|
||||
@ -325,6 +251,14 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@babel/types@7.17.0:
|
||||
resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.22.5
|
||||
to-fast-properties: 2.0.0
|
||||
dev: true
|
||||
|
||||
/@babel/types@7.22.5:
|
||||
resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@ -333,6 +267,10 @@ packages:
|
||||
'@babel/helper-validator-identifier': 7.22.5
|
||||
to-fast-properties: 2.0.0
|
||||
|
||||
/@bufbuild/protobuf@1.3.0:
|
||||
resolution: {integrity: sha512-G372ods0pLt46yxVRsnP/e2btVPuuzArcMPFpIDeIwiGPuuglEs9y75iG0HMvZgncsj5TvbYRWqbVyOe3PLCWQ==}
|
||||
dev: false
|
||||
|
||||
/@emotion/babel-plugin@11.11.0:
|
||||
resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==}
|
||||
dependencies:
|
||||
@ -704,26 +642,6 @@ packages:
|
||||
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
|
||||
dev: true
|
||||
|
||||
/@ianvs/prettier-plugin-sort-imports@4.1.0(prettier@2.5.1):
|
||||
resolution: {integrity: sha512-IAXeTLU24k6mRPa6mFbW1qZJ/j0m3OeH44wyijWyr+YqqdNtBnfHxAntOAATS9iDfrT01NesKGsdzqnXdDQa/A==}
|
||||
peerDependencies:
|
||||
'@vue/compiler-sfc': '>=3.0.0'
|
||||
prettier: 2 || 3
|
||||
peerDependenciesMeta:
|
||||
'@vue/compiler-sfc':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/core': 7.22.9
|
||||
'@babel/generator': 7.22.9
|
||||
'@babel/parser': 7.22.7
|
||||
'@babel/traverse': 7.22.8
|
||||
'@babel/types': 7.22.5
|
||||
prettier: 2.5.1
|
||||
semver: 7.5.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@jridgewell/gen-mapping@0.3.3:
|
||||
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@ -1066,6 +984,26 @@ packages:
|
||||
'@swc/core-win32-x64-msvc': 1.3.73
|
||||
dev: true
|
||||
|
||||
/@trivago/prettier-plugin-sort-imports@4.1.0(prettier@2.6.2):
|
||||
resolution: {integrity: sha512-aTr6QPFaPAAzPRFn9yWB/9yKi3ZAFqfGpxIGLPWuQfYJFGUed+W3KKwxntsoCiNvNE2iuKOg6haMo5KG8WXltg==}
|
||||
peerDependencies:
|
||||
'@vue/compiler-sfc': 3.x
|
||||
prettier: 2.x
|
||||
peerDependenciesMeta:
|
||||
'@vue/compiler-sfc':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/generator': 7.17.7
|
||||
'@babel/parser': 7.22.7
|
||||
'@babel/traverse': 7.17.3
|
||||
'@babel/types': 7.17.0
|
||||
javascript-natural-sort: 0.7.1
|
||||
lodash: 4.17.21
|
||||
prettier: 2.6.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@types/hoist-non-react-statics@3.3.1:
|
||||
resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==}
|
||||
dependencies:
|
||||
@ -1259,13 +1197,13 @@ packages:
|
||||
eslint-visitor-keys: 3.4.2
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-react-swc@3.0.0(vite@4.2.1):
|
||||
/@vitejs/plugin-react-swc@3.0.0(vite@4.2.3):
|
||||
resolution: {integrity: sha512-vYlodz/mjYRbxMGbHzDgR8aPR+z8n7K/enWkyBGH096xrL2DIPCuTvQVRYPTXGyy6wO7OFiMxZ3r4nKQD1sH0A==}
|
||||
peerDependencies:
|
||||
vite: ^4.0.0
|
||||
dependencies:
|
||||
'@swc/core': 1.3.73
|
||||
vite: 4.2.1(@types/node@20.3.1)
|
||||
vite: 4.2.3(@types/node@20.3.1)
|
||||
transitivePeerDependencies:
|
||||
- '@swc/helpers'
|
||||
dev: true
|
||||
@ -1556,6 +1494,7 @@ packages:
|
||||
|
||||
/convert-source-map@1.9.0:
|
||||
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
|
||||
dev: false
|
||||
|
||||
/copy-to-clipboard@3.3.2:
|
||||
resolution: {integrity: sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==}
|
||||
@ -1785,7 +1724,7 @@ packages:
|
||||
eslint: 8.46.0
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-prettier@4.0.0(eslint-config-prettier@8.3.0)(eslint@8.46.0)(prettier@2.5.1):
|
||||
/eslint-plugin-prettier@4.0.0(eslint-config-prettier@8.3.0)(eslint@8.46.0)(prettier@2.6.2):
|
||||
resolution: {integrity: sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
peerDependencies:
|
||||
@ -1798,7 +1737,7 @@ packages:
|
||||
dependencies:
|
||||
eslint: 8.46.0
|
||||
eslint-config-prettier: 8.3.0(eslint@8.46.0)
|
||||
prettier: 2.5.1
|
||||
prettier: 2.6.2
|
||||
prettier-linter-helpers: 1.0.0
|
||||
dev: true
|
||||
|
||||
@ -2041,11 +1980,6 @@ packages:
|
||||
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
||||
dev: true
|
||||
|
||||
/gensync@1.0.0-beta.2:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/get-intrinsic@1.2.1:
|
||||
resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
|
||||
dependencies:
|
||||
@ -2375,6 +2309,10 @@ packages:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
dev: true
|
||||
|
||||
/javascript-natural-sort@0.7.1:
|
||||
resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==}
|
||||
dev: true
|
||||
|
||||
/jiti@1.19.1:
|
||||
resolution: {integrity: sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==}
|
||||
hasBin: true
|
||||
@ -2408,12 +2346,6 @@ packages:
|
||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||
dev: true
|
||||
|
||||
/json5@2.2.3:
|
||||
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
|
||||
engines: {node: '>=6'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/jsx-ast-utils@3.3.5:
|
||||
resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
@ -2456,18 +2388,16 @@ packages:
|
||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||
dev: true
|
||||
|
||||
/lodash@4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
dev: true
|
||||
|
||||
/loose-envify@1.4.0:
|
||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
js-tokens: 4.0.0
|
||||
|
||||
/lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
dependencies:
|
||||
yallist: 3.1.1
|
||||
dev: true
|
||||
|
||||
/lru-cache@6.0.0:
|
||||
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
||||
engines: {node: '>=10'}
|
||||
@ -2773,7 +2703,6 @@ packages:
|
||||
nanoid: 3.3.6
|
||||
picocolors: 1.0.0
|
||||
source-map-js: 1.0.2
|
||||
dev: false
|
||||
|
||||
/prelude-ls@1.2.1:
|
||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||
@ -2787,8 +2716,8 @@ packages:
|
||||
fast-diff: 1.3.0
|
||||
dev: true
|
||||
|
||||
/prettier@2.5.1:
|
||||
resolution: {integrity: sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==}
|
||||
/prettier@2.6.2:
|
||||
resolution: {integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
@ -3089,7 +3018,6 @@ packages:
|
||||
/source-map@0.5.7:
|
||||
resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/string.prototype.matchall@4.0.8:
|
||||
resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==}
|
||||
@ -3346,8 +3274,8 @@ packages:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
dev: false
|
||||
|
||||
/vite@4.2.1(@types/node@20.3.1):
|
||||
resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==}
|
||||
/vite@4.2.3(@types/node@20.3.1):
|
||||
resolution: {integrity: sha512-kLU+m2q0Y434Y1kCy3TchefAdtFso0ILi0dLyFV8Us3InXTU11H/B5ZTqCKIQHzSKNxVG/yEx813EA9f1imQ9A==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@ -3373,7 +3301,7 @@ packages:
|
||||
dependencies:
|
||||
'@types/node': 20.3.1
|
||||
esbuild: 0.17.19
|
||||
postcss: 8.4.21
|
||||
postcss: 8.4.27
|
||||
resolve: 1.22.2
|
||||
rollup: 3.27.0
|
||||
optionalDependencies:
|
||||
@ -3417,10 +3345,6 @@ packages:
|
||||
/wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
/yallist@3.1.1:
|
||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||
dev: true
|
||||
|
||||
/yallist@4.0.0:
|
||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||
dev: true
|
||||
|
@ -54,7 +54,7 @@ const Alert: React.FC<Props> = (props: Props) => {
|
||||
<div className="w-80">
|
||||
<p className="content-text mb-4">{content}</p>
|
||||
<div className="w-full flex flex-row justify-end items-center space-x-2">
|
||||
<Button variant="plain" onClick={handleCloseBtnClick}>
|
||||
<Button variant="plain" color="neutral" onClick={handleCloseBtnClick}>
|
||||
{closeBtnText}
|
||||
</Button>
|
||||
<Button color={style} onClick={handleConfirmBtnClick}>
|
||||
|
134
web/src/components/CreateAccessTokenDialog.tsx
Normal file
@ -0,0 +1,134 @@
|
||||
import { Button, Input, Modal, ModalDialog, Radio, RadioGroup } from "@mui/joy";
|
||||
import axios from "axios";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import useLoading from "../hooks/useLoading";
|
||||
import useUserStore from "../stores/v1/user";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
onConfirm?: () => void;
|
||||
}
|
||||
|
||||
const expirationOptions = [
|
||||
{
|
||||
label: "8 hours",
|
||||
value: 3600 * 8,
|
||||
},
|
||||
{
|
||||
label: "1 month",
|
||||
value: 3600 * 24 * 30,
|
||||
},
|
||||
{
|
||||
label: "Never",
|
||||
value: 0,
|
||||
},
|
||||
];
|
||||
|
||||
interface State {
|
||||
description: string;
|
||||
expiration: number;
|
||||
}
|
||||
|
||||
const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
|
||||
const { onClose, onConfirm } = props;
|
||||
const currentUser = useUserStore().getCurrentUser();
|
||||
const [state, setState] = useState({
|
||||
description: "",
|
||||
expiration: 3600 * 8,
|
||||
});
|
||||
const requestState = useLoading(false);
|
||||
|
||||
const setPartialState = (partialState: Partial<State>) => {
|
||||
setState({
|
||||
...state,
|
||||
...partialState,
|
||||
});
|
||||
};
|
||||
|
||||
const handleDescriptionInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setPartialState({
|
||||
description: e.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleRoleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setPartialState({
|
||||
expiration: Number(e.target.value),
|
||||
});
|
||||
};
|
||||
|
||||
const handleSaveBtnClick = async () => {
|
||||
if (!state.description) {
|
||||
toast.error("Description is required");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await axios.post(`/api/v2/users/${currentUser.id}/access_tokens`, {
|
||||
description: state.description,
|
||||
expiresAt: new Date(Date.now() + state.expiration * 1000),
|
||||
});
|
||||
|
||||
if (onConfirm) {
|
||||
onConfirm();
|
||||
}
|
||||
onClose();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error(error.response.data.message);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal open={true}>
|
||||
<ModalDialog>
|
||||
<div className="flex flex-row justify-between items-center w-80 sm:w-96 mb-4">
|
||||
<span className="text-lg font-medium">Create Access Token</span>
|
||||
<Button variant="plain" onClick={onClose}>
|
||||
<Icon.X className="w-5 h-auto text-gray-600" />
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||
<span className="mb-2">
|
||||
Description <span className="text-red-600">*</span>
|
||||
</span>
|
||||
<div className="relative w-full">
|
||||
<Input
|
||||
className="w-full"
|
||||
type="text"
|
||||
placeholder="Some description"
|
||||
value={state.description}
|
||||
onChange={handleDescriptionInputChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||
<span className="mb-2">
|
||||
Expiration <span className="text-red-600">*</span>
|
||||
</span>
|
||||
<div className="w-full flex flex-row justify-start items-center text-base">
|
||||
<RadioGroup orientation="horizontal" value={state.expiration} onChange={handleRoleInputChange}>
|
||||
{expirationOptions.map((option) => (
|
||||
<Radio key={option.value} value={option.value} label={option.label} />
|
||||
))}
|
||||
</RadioGroup>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full flex flex-row justify-end items-center mt-4 space-x-2">
|
||||
<Button color="neutral" variant="plain" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
|
||||
Create
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalDialog>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateAccessTokenDialog;
|
@ -4,8 +4,8 @@ import { Link } from "react-router-dom";
|
||||
import * as api from "../helpers/api";
|
||||
import useUserStore from "../stores/v1/user";
|
||||
import AboutDialog from "./AboutDialog";
|
||||
import Dropdown from "./common/Dropdown";
|
||||
import Icon from "./Icon";
|
||||
import Dropdown from "./common/Dropdown";
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const currentUser = useUserStore().getCurrentUser();
|
||||
|
@ -3,10 +3,10 @@ import { shortcutService } from "../services";
|
||||
import useUserStore from "../stores/v1/user";
|
||||
import { showCommonDialog } from "./Alert";
|
||||
import AnalyticsDialog from "./AnalyticsDialog";
|
||||
import Dropdown from "./common/Dropdown";
|
||||
import CreateShortcutDialog from "./CreateShortcutDialog";
|
||||
import GenerateQRCodeDialog from "./GenerateQRCodeDialog";
|
||||
import Icon from "./Icon";
|
||||
import Dropdown from "./common/Dropdown";
|
||||
|
||||
interface Props {
|
||||
shortcut: Shortcut;
|
||||
|
@ -84,7 +84,7 @@ const ShortcutView = (props: Props) => {
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<a className="ml-1 w-full text-sm truncate text-gray-400 hover:underline" href={shortcut.link} target="_blank">
|
||||
<a className="pl-1 pr-4 w-full text-sm truncate text-gray-400 hover:underline" href={shortcut.link} target="_blank">
|
||||
{shortcut.link}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Button, Divider, Option, Select } from "@mui/joy";
|
||||
import { toast } from "react-hot-toast";
|
||||
import useViewStore from "../stores/v1/view";
|
||||
import Dropdown from "./common/Dropdown";
|
||||
import Icon from "./Icon";
|
||||
import Dropdown from "./common/Dropdown";
|
||||
|
||||
const ViewSetting = () => {
|
||||
const viewStore = useViewStore();
|
||||
|
141
web/src/components/setting/AccessTokenSection.tsx
Normal file
@ -0,0 +1,141 @@
|
||||
import { Button } from "@mui/joy";
|
||||
import axios from "axios";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import useUserStore from "../../stores/v1/user";
|
||||
import { ListUserAccessTokensResponse, UserAccessToken } from "../../types/proto/api/v2/user_service_pb";
|
||||
import { showCommonDialog } from "../Alert";
|
||||
import CreateAccessTokenDialog from "../CreateAccessTokenDialog";
|
||||
import Icon from "../Icon";
|
||||
|
||||
const listAccessTokens = async (userId: number) => {
|
||||
const { data } = await axios.get<ListUserAccessTokensResponse>(`/api/v2/users/${userId}/access_tokens`);
|
||||
return data.accessTokens;
|
||||
};
|
||||
|
||||
const AccessTokenSection = () => {
|
||||
const currentUser = useUserStore().getCurrentUser();
|
||||
const [userAccessTokens, setUserAccessTokens] = useState<UserAccessToken[]>([]);
|
||||
const [showCreateDialog, setShowCreateDialog] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
listAccessTokens(currentUser.id).then((accessTokens) => {
|
||||
setUserAccessTokens(accessTokens);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleCreateAccessTokenDialogConfirm = async () => {
|
||||
const accessTokens = await listAccessTokens(currentUser.id);
|
||||
setUserAccessTokens(accessTokens);
|
||||
};
|
||||
|
||||
const copyAccessToken = (accessToken: string) => {
|
||||
copy(accessToken);
|
||||
toast.success("Access token copied to clipboard");
|
||||
};
|
||||
|
||||
const handleDeleteAccessToken = async (accessToken: string) => {
|
||||
showCommonDialog({
|
||||
title: "Delete Access Token",
|
||||
content: `Are you sure to delete access token \`${getFormatedAccessToken(accessToken)}\`? You cannot undo this action.`,
|
||||
style: "danger",
|
||||
onConfirm: async () => {
|
||||
await axios.delete(`/api/v2/users/${currentUser.id}/access_tokens/${accessToken}`);
|
||||
setUserAccessTokens(userAccessTokens.filter((token) => token.accessToken !== accessToken));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const getFormatedAccessToken = (accessToken: string) => {
|
||||
return `${accessToken.slice(0, 4)}****${accessToken.slice(-4)}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full flex flex-col justify-start items-start space-y-4">
|
||||
<div className="w-full">
|
||||
<div className="sm:flex sm:items-center">
|
||||
<div className="sm:flex-auto">
|
||||
<p className="text-base font-semibold leading-6 text-gray-900">Access Tokens</p>
|
||||
<p className="mt-2 text-sm text-gray-700">A list of all access tokens for your account.</p>
|
||||
</div>
|
||||
<div className="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="neutral"
|
||||
onClick={() => {
|
||||
setShowCreateDialog(true);
|
||||
}}
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-2 flow-root">
|
||||
<div className="overflow-x-auto">
|
||||
<div className="inline-block min-w-full py-2 align-middle">
|
||||
<table className="min-w-full divide-y divide-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Token
|
||||
</th>
|
||||
<th scope="col" className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900">
|
||||
Description
|
||||
</th>
|
||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Created At
|
||||
</th>
|
||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Expires At
|
||||
</th>
|
||||
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
||||
<span className="sr-only">Delete</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200">
|
||||
{userAccessTokens.map((userAccessToken) => (
|
||||
<tr key={userAccessToken.accessToken}>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-900 flex flex-row justify-start items-center gap-x-1">
|
||||
<span className="font-mono">{getFormatedAccessToken(userAccessToken.accessToken)}</span>
|
||||
<Button color="neutral" variant="plain" size="sm" onClick={() => copyAccessToken(userAccessToken.accessToken)}>
|
||||
<Icon.Clipboard className="w-4 h-auto text-gray-500" />
|
||||
</Button>
|
||||
</td>
|
||||
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-900">{userAccessToken.description}</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{String(userAccessToken.issuedAt)}</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
{String(userAccessToken.expiresAt ?? "Never")}
|
||||
</td>
|
||||
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm">
|
||||
<Button
|
||||
color="danger"
|
||||
variant="plain"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
handleDeleteAccessToken(userAccessToken.accessToken);
|
||||
}}
|
||||
>
|
||||
<Icon.Trash className="w-4 h-auto" />
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{showCreateDialog && (
|
||||
<CreateAccessTokenDialog onClose={() => setShowCreateDialog(false)} onConfirm={handleCreateAccessTokenDialogConfirm} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AccessTokenSection;
|
@ -12,7 +12,7 @@ const AccountSection: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-auto max-w-6xl w-full px-3 md:px-12 py-6 flex flex-col justify-start items-start gap-y-2">
|
||||
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
||||
<p className="text-base font-semibold leading-6 text-gray-900">Account</p>
|
||||
<p className="flex flex-row justify-start items-center mt-2">
|
||||
<span className="text-xl">{currentUser.nickname}</span>
|
||||
|
@ -20,7 +20,7 @@ const MemberSection = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mx-auto max-w-6xl w-full px-3 md:px-12 py-6 flex flex-col justify-start items-start space-y-4">
|
||||
<div className="w-full flex flex-col justify-start items-start space-y-4">
|
||||
<div className="w-full">
|
||||
<div className="sm:flex sm:items-center">
|
||||
<div className="sm:flex-auto">
|
||||
@ -31,6 +31,8 @@ const MemberSection = () => {
|
||||
</div>
|
||||
<div className="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="neutral"
|
||||
onClick={() => {
|
||||
setShowCreateUserDialog(true);
|
||||
setCurrentEditingUser(undefined);
|
@ -17,7 +17,7 @@ const WorkspaceSection: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-6xl w-full px-3 md:px-12 py-6 flex flex-col justify-start items-start space-y-4">
|
||||
<div className="w-full flex flex-col justify-start items-start space-y-4">
|
||||
<p className="text-base font-semibold leading-6 text-gray-900">Workspace settings</p>
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<Checkbox
|
||||
|
@ -3,10 +3,10 @@ import { createRoot } from "react-dom/client";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { Provider } from "react-redux";
|
||||
import { RouterProvider } from "react-router-dom";
|
||||
import "./css/index.css";
|
||||
import "./i18n";
|
||||
import router from "./routers";
|
||||
import store from "./stores";
|
||||
import "./i18n";
|
||||
import "./css/index.css";
|
||||
|
||||
const container = document.getElementById("root");
|
||||
const root = createRoot(container as HTMLElement);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import AccessTokenSection from "../components/setting/AccessTokenSection";
|
||||
import AccountSection from "../components/setting/AccountSection";
|
||||
import UserSection from "../components/setting/UserSection";
|
||||
import MemberSection from "../components/setting/MemberSection";
|
||||
import WorkspaceSection from "../components/setting/WorkspaceSection";
|
||||
import useUserStore from "../stores/v1/user";
|
||||
|
||||
@ -8,11 +9,12 @@ const Setting: React.FC = () => {
|
||||
const isAdmin = currentUser.role === "ADMIN";
|
||||
|
||||
return (
|
||||
<div className="mx-auto max-w-6xl w-full px-3 md:px-12 py-6 flex flex-col justify-start items-start space-y-4">
|
||||
<div className="mx-auto max-w-6xl w-full px-3 md:px-12 py-6 flex flex-col justify-start items-start gap-y-12">
|
||||
<AccountSection />
|
||||
<AccessTokenSection />
|
||||
{isAdmin && (
|
||||
<>
|
||||
<UserSection />
|
||||
<MemberSection />
|
||||
<WorkspaceSection />
|
||||
</>
|
||||
)}
|
||||
|
@ -7,11 +7,11 @@ import { useTranslation } from "react-i18next";
|
||||
import { useLoaderData, useNavigate } from "react-router-dom";
|
||||
import { showCommonDialog } from "../components/Alert";
|
||||
import AnalyticsView from "../components/AnalyticsView";
|
||||
import Dropdown from "../components/common/Dropdown";
|
||||
import CreateShortcutDialog from "../components/CreateShortcutDialog";
|
||||
import GenerateQRCodeDialog from "../components/GenerateQRCodeDialog";
|
||||
import Icon from "../components/Icon";
|
||||
import VisibilityIcon from "../components/VisibilityIcon";
|
||||
import Dropdown from "../components/common/Dropdown";
|
||||
import { absolutifyLink } from "../helpers/utils";
|
||||
import { shortcutService } from "../services";
|
||||
import useFaviconStore from "../stores/v1/favicon";
|
||||
|
25
web/src/types/proto/api/v2/common_pb.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/common.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.RowStatus
|
||||
*/
|
||||
export declare enum RowStatus {
|
||||
/**
|
||||
* @generated from enum value: ROW_STATUS_UNSPECIFIED = 0;
|
||||
*/
|
||||
ROW_STATUS_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: NORMAL = 1;
|
||||
*/
|
||||
NORMAL = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: ARCHIVED = 2;
|
||||
*/
|
||||
ARCHIVED = 2,
|
||||
}
|
||||
|
19
web/src/types/proto/api/v2/common_pb.js
Normal file
@ -0,0 +1,19 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/common.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.RowStatus
|
||||
*/
|
||||
export const RowStatus = proto3.makeEnum(
|
||||
"slash.api.v2.RowStatus",
|
||||
[
|
||||
{no: 0, name: "ROW_STATUS_UNSPECIFIED"},
|
||||
{no: 1, name: "NORMAL"},
|
||||
{no: 2, name: "ARCHIVED"},
|
||||
],
|
||||
);
|
||||
|
238
web/src/types/proto/api/v2/shortcut_service_pb.d.ts
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/shortcut_service.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
|
||||
import { Message, proto3 } from "@bufbuild/protobuf";
|
||||
import type { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.Visibility
|
||||
*/
|
||||
export declare enum Visibility {
|
||||
/**
|
||||
* @generated from enum value: VISIBILITY_UNSPECIFIED = 0;
|
||||
*/
|
||||
VISIBILITY_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: PRIVATE = 1;
|
||||
*/
|
||||
PRIVATE = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: WORKSPACE = 2;
|
||||
*/
|
||||
WORKSPACE = 2,
|
||||
|
||||
/**
|
||||
* @generated from enum value: PUBLIC = 3;
|
||||
*/
|
||||
PUBLIC = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.Shortcut
|
||||
*/
|
||||
export declare class Shortcut extends Message<Shortcut> {
|
||||
/**
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @generated from field: int32 creator_id = 2;
|
||||
*/
|
||||
creatorId: number;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 created_ts = 3;
|
||||
*/
|
||||
createdTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 updated_ts = 4;
|
||||
*/
|
||||
updatedTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.RowStatus row_status = 5;
|
||||
*/
|
||||
rowStatus: RowStatus;
|
||||
|
||||
/**
|
||||
* @generated from field: string name = 6;
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string link = 7;
|
||||
*/
|
||||
link: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string title = 8;
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* @generated from field: repeated string tags = 9;
|
||||
*/
|
||||
tags: string[];
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 10;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.Visibility visibility = 11;
|
||||
*/
|
||||
visibility: Visibility;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.OpenGraphMetadata og_metadata = 12;
|
||||
*/
|
||||
ogMetadata?: OpenGraphMetadata;
|
||||
|
||||
constructor(data?: PartialMessage<Shortcut>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.Shortcut";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Shortcut;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Shortcut;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Shortcut;
|
||||
|
||||
static equals(a: Shortcut | PlainMessage<Shortcut> | undefined, b: Shortcut | PlainMessage<Shortcut> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.OpenGraphMetadata
|
||||
*/
|
||||
export declare class OpenGraphMetadata extends Message<OpenGraphMetadata> {
|
||||
/**
|
||||
* @generated from field: string title = 1;
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 2;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string image = 3;
|
||||
*/
|
||||
image: string;
|
||||
|
||||
constructor(data?: PartialMessage<OpenGraphMetadata>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.OpenGraphMetadata";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static equals(a: OpenGraphMetadata | PlainMessage<OpenGraphMetadata> | undefined, b: OpenGraphMetadata | PlainMessage<OpenGraphMetadata> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListShortcutsRequest
|
||||
*/
|
||||
export declare class ListShortcutsRequest extends Message<ListShortcutsRequest> {
|
||||
constructor(data?: PartialMessage<ListShortcutsRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.ListShortcutsRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListShortcutsRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListShortcutsRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListShortcutsRequest;
|
||||
|
||||
static equals(a: ListShortcutsRequest | PlainMessage<ListShortcutsRequest> | undefined, b: ListShortcutsRequest | PlainMessage<ListShortcutsRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListShortcutsResponse
|
||||
*/
|
||||
export declare class ListShortcutsResponse extends Message<ListShortcutsResponse> {
|
||||
/**
|
||||
* @generated from field: repeated slash.api.v2.Shortcut shortcuts = 1;
|
||||
*/
|
||||
shortcuts: Shortcut[];
|
||||
|
||||
constructor(data?: PartialMessage<ListShortcutsResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.ListShortcutsResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListShortcutsResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListShortcutsResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListShortcutsResponse;
|
||||
|
||||
static equals(a: ListShortcutsResponse | PlainMessage<ListShortcutsResponse> | undefined, b: ListShortcutsResponse | PlainMessage<ListShortcutsResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetShortcutRequest
|
||||
*/
|
||||
export declare class GetShortcutRequest extends Message<GetShortcutRequest> {
|
||||
/**
|
||||
* @generated from field: string name = 1;
|
||||
*/
|
||||
name: string;
|
||||
|
||||
constructor(data?: PartialMessage<GetShortcutRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.GetShortcutRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetShortcutRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetShortcutRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetShortcutRequest;
|
||||
|
||||
static equals(a: GetShortcutRequest | PlainMessage<GetShortcutRequest> | undefined, b: GetShortcutRequest | PlainMessage<GetShortcutRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetShortcutResponse
|
||||
*/
|
||||
export declare class GetShortcutResponse extends Message<GetShortcutResponse> {
|
||||
/**
|
||||
* @generated from field: slash.api.v2.Shortcut shortcut = 1;
|
||||
*/
|
||||
shortcut?: Shortcut;
|
||||
|
||||
constructor(data?: PartialMessage<GetShortcutResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.GetShortcutResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetShortcutResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetShortcutResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetShortcutResponse;
|
||||
|
||||
static equals(a: GetShortcutResponse | PlainMessage<GetShortcutResponse> | undefined, b: GetShortcutResponse | PlainMessage<GetShortcutResponse> | undefined): boolean;
|
||||
}
|
||||
|
92
web/src/types/proto/api/v2/shortcut_service_pb.js
Normal file
@ -0,0 +1,92 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/shortcut_service.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
import { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.Visibility
|
||||
*/
|
||||
export const Visibility = proto3.makeEnum(
|
||||
"slash.api.v2.Visibility",
|
||||
[
|
||||
{no: 0, name: "VISIBILITY_UNSPECIFIED"},
|
||||
{no: 1, name: "PRIVATE"},
|
||||
{no: 2, name: "WORKSPACE"},
|
||||
{no: 3, name: "PUBLIC"},
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.Shortcut
|
||||
*/
|
||||
export const Shortcut = proto3.makeMessageType(
|
||||
"slash.api.v2.Shortcut",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "creator_id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 3, name: "created_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 4, name: "updated_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 5, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) },
|
||||
{ no: 6, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 7, name: "link", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 8, name: "title", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 9, name: "tags", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
||||
{ no: 10, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 11, name: "visibility", kind: "enum", T: proto3.getEnumType(Visibility) },
|
||||
{ no: 12, name: "og_metadata", kind: "message", T: OpenGraphMetadata },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.OpenGraphMetadata
|
||||
*/
|
||||
export const OpenGraphMetadata = proto3.makeMessageType(
|
||||
"slash.api.v2.OpenGraphMetadata",
|
||||
() => [
|
||||
{ no: 1, name: "title", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 3, name: "image", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListShortcutsRequest
|
||||
*/
|
||||
export const ListShortcutsRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.ListShortcutsRequest",
|
||||
[],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListShortcutsResponse
|
||||
*/
|
||||
export const ListShortcutsResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.ListShortcutsResponse",
|
||||
() => [
|
||||
{ no: 1, name: "shortcuts", kind: "message", T: Shortcut, repeated: true },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetShortcutRequest
|
||||
*/
|
||||
export const GetShortcutRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.GetShortcutRequest",
|
||||
() => [
|
||||
{ no: 1, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetShortcutResponse
|
||||
*/
|
||||
export const GetShortcutResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.GetShortcutResponse",
|
||||
() => [
|
||||
{ no: 1, name: "shortcut", kind: "message", T: Shortcut },
|
||||
],
|
||||
);
|
||||
|
327
web/src/types/proto/api/v2/user_service_pb.d.ts
vendored
Normal file
@ -0,0 +1,327 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/user_service.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage, Timestamp } from "@bufbuild/protobuf";
|
||||
import { Message, proto3 } from "@bufbuild/protobuf";
|
||||
import type { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.Role
|
||||
*/
|
||||
export declare enum Role {
|
||||
/**
|
||||
* @generated from enum value: ROLE_UNSPECIFIED = 0;
|
||||
*/
|
||||
ROLE_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: ADMIN = 1;
|
||||
*/
|
||||
ADMIN = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: USER = 2;
|
||||
*/
|
||||
USER = 2,
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.User
|
||||
*/
|
||||
export declare class User extends Message<User> {
|
||||
/**
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.RowStatus row_status = 2;
|
||||
*/
|
||||
rowStatus: RowStatus;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 created_ts = 3;
|
||||
*/
|
||||
createdTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 updated_ts = 4;
|
||||
*/
|
||||
updatedTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.Role role = 6;
|
||||
*/
|
||||
role: Role;
|
||||
|
||||
/**
|
||||
* @generated from field: string email = 7;
|
||||
*/
|
||||
email: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string nickname = 8;
|
||||
*/
|
||||
nickname: string;
|
||||
|
||||
constructor(data?: PartialMessage<User>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.User";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): User;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): User;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): User;
|
||||
|
||||
static equals(a: User | PlainMessage<User> | undefined, b: User | PlainMessage<User> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetUserRequest
|
||||
*/
|
||||
export declare class GetUserRequest extends Message<GetUserRequest> {
|
||||
/**
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
constructor(data?: PartialMessage<GetUserRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.GetUserRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetUserRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetUserRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetUserRequest;
|
||||
|
||||
static equals(a: GetUserRequest | PlainMessage<GetUserRequest> | undefined, b: GetUserRequest | PlainMessage<GetUserRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetUserResponse
|
||||
*/
|
||||
export declare class GetUserResponse extends Message<GetUserResponse> {
|
||||
/**
|
||||
* @generated from field: slash.api.v2.User user = 1;
|
||||
*/
|
||||
user?: User;
|
||||
|
||||
constructor(data?: PartialMessage<GetUserResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.GetUserResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetUserResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetUserResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetUserResponse;
|
||||
|
||||
static equals(a: GetUserResponse | PlainMessage<GetUserResponse> | undefined, b: GetUserResponse | PlainMessage<GetUserResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListUserAccessTokensRequest
|
||||
*/
|
||||
export declare class ListUserAccessTokensRequest extends Message<ListUserAccessTokensRequest> {
|
||||
/**
|
||||
* id is the user id.
|
||||
*
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
constructor(data?: PartialMessage<ListUserAccessTokensRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.ListUserAccessTokensRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListUserAccessTokensRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListUserAccessTokensRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListUserAccessTokensRequest;
|
||||
|
||||
static equals(a: ListUserAccessTokensRequest | PlainMessage<ListUserAccessTokensRequest> | undefined, b: ListUserAccessTokensRequest | PlainMessage<ListUserAccessTokensRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListUserAccessTokensResponse
|
||||
*/
|
||||
export declare class ListUserAccessTokensResponse extends Message<ListUserAccessTokensResponse> {
|
||||
/**
|
||||
* @generated from field: repeated slash.api.v2.UserAccessToken access_tokens = 1;
|
||||
*/
|
||||
accessTokens: UserAccessToken[];
|
||||
|
||||
constructor(data?: PartialMessage<ListUserAccessTokensResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.ListUserAccessTokensResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ListUserAccessTokensResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ListUserAccessTokensResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ListUserAccessTokensResponse;
|
||||
|
||||
static equals(a: ListUserAccessTokensResponse | PlainMessage<ListUserAccessTokensResponse> | undefined, b: ListUserAccessTokensResponse | PlainMessage<ListUserAccessTokensResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.CreateUserAccessTokenRequest
|
||||
*/
|
||||
export declare class CreateUserAccessTokenRequest extends Message<CreateUserAccessTokenRequest> {
|
||||
/**
|
||||
* id is the user id.
|
||||
*
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.api.v2.UserAccessToken user_access_token = 2;
|
||||
*/
|
||||
userAccessToken?: UserAccessToken;
|
||||
|
||||
constructor(data?: PartialMessage<CreateUserAccessTokenRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.CreateUserAccessTokenRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateUserAccessTokenRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateUserAccessTokenRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateUserAccessTokenRequest;
|
||||
|
||||
static equals(a: CreateUserAccessTokenRequest | PlainMessage<CreateUserAccessTokenRequest> | undefined, b: CreateUserAccessTokenRequest | PlainMessage<CreateUserAccessTokenRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.CreateUserAccessTokenResponse
|
||||
*/
|
||||
export declare class CreateUserAccessTokenResponse extends Message<CreateUserAccessTokenResponse> {
|
||||
/**
|
||||
* @generated from field: slash.api.v2.UserAccessToken access_token = 1;
|
||||
*/
|
||||
accessToken?: UserAccessToken;
|
||||
|
||||
constructor(data?: PartialMessage<CreateUserAccessTokenResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.CreateUserAccessTokenResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateUserAccessTokenResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateUserAccessTokenResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateUserAccessTokenResponse;
|
||||
|
||||
static equals(a: CreateUserAccessTokenResponse | PlainMessage<CreateUserAccessTokenResponse> | undefined, b: CreateUserAccessTokenResponse | PlainMessage<CreateUserAccessTokenResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.DeleteUserAccessTokenRequest
|
||||
*/
|
||||
export declare class DeleteUserAccessTokenRequest extends Message<DeleteUserAccessTokenRequest> {
|
||||
/**
|
||||
* id is the user id.
|
||||
*
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* access_token is the access token to delete.
|
||||
*
|
||||
* @generated from field: string access_token = 2;
|
||||
*/
|
||||
accessToken: string;
|
||||
|
||||
constructor(data?: PartialMessage<DeleteUserAccessTokenRequest>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.DeleteUserAccessTokenRequest";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): DeleteUserAccessTokenRequest;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): DeleteUserAccessTokenRequest;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): DeleteUserAccessTokenRequest;
|
||||
|
||||
static equals(a: DeleteUserAccessTokenRequest | PlainMessage<DeleteUserAccessTokenRequest> | undefined, b: DeleteUserAccessTokenRequest | PlainMessage<DeleteUserAccessTokenRequest> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.DeleteUserAccessTokenResponse
|
||||
*/
|
||||
export declare class DeleteUserAccessTokenResponse extends Message<DeleteUserAccessTokenResponse> {
|
||||
constructor(data?: PartialMessage<DeleteUserAccessTokenResponse>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.DeleteUserAccessTokenResponse";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): DeleteUserAccessTokenResponse;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): DeleteUserAccessTokenResponse;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): DeleteUserAccessTokenResponse;
|
||||
|
||||
static equals(a: DeleteUserAccessTokenResponse | PlainMessage<DeleteUserAccessTokenResponse> | undefined, b: DeleteUserAccessTokenResponse | PlainMessage<DeleteUserAccessTokenResponse> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.UserAccessToken
|
||||
*/
|
||||
export declare class UserAccessToken extends Message<UserAccessToken> {
|
||||
/**
|
||||
* @generated from field: string access_token = 1;
|
||||
*/
|
||||
accessToken: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 2;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp issued_at = 3;
|
||||
*/
|
||||
issuedAt?: Timestamp;
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp expires_at = 4;
|
||||
*/
|
||||
expiresAt?: Timestamp;
|
||||
|
||||
constructor(data?: PartialMessage<UserAccessToken>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.api.v2.UserAccessToken";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UserAccessToken;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): UserAccessToken;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): UserAccessToken;
|
||||
|
||||
static equals(a: UserAccessToken | PlainMessage<UserAccessToken> | undefined, b: UserAccessToken | PlainMessage<UserAccessToken> | undefined): boolean;
|
||||
}
|
||||
|
129
web/src/types/proto/api/v2/user_service_pb.js
Normal file
@ -0,0 +1,129 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file api/v2/user_service.proto (package slash.api.v2, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3, Timestamp } from "@bufbuild/protobuf";
|
||||
import { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.api.v2.Role
|
||||
*/
|
||||
export const Role = proto3.makeEnum(
|
||||
"slash.api.v2.Role",
|
||||
[
|
||||
{no: 0, name: "ROLE_UNSPECIFIED"},
|
||||
{no: 1, name: "ADMIN"},
|
||||
{no: 2, name: "USER"},
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.User
|
||||
*/
|
||||
export const User = proto3.makeMessageType(
|
||||
"slash.api.v2.User",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) },
|
||||
{ no: 3, name: "created_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 4, name: "updated_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 6, name: "role", kind: "enum", T: proto3.getEnumType(Role) },
|
||||
{ no: 7, name: "email", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 8, name: "nickname", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetUserRequest
|
||||
*/
|
||||
export const GetUserRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.GetUserRequest",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.GetUserResponse
|
||||
*/
|
||||
export const GetUserResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.GetUserResponse",
|
||||
() => [
|
||||
{ no: 1, name: "user", kind: "message", T: User },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListUserAccessTokensRequest
|
||||
*/
|
||||
export const ListUserAccessTokensRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.ListUserAccessTokensRequest",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.ListUserAccessTokensResponse
|
||||
*/
|
||||
export const ListUserAccessTokensResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.ListUserAccessTokensResponse",
|
||||
() => [
|
||||
{ no: 1, name: "access_tokens", kind: "message", T: UserAccessToken, repeated: true },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.CreateUserAccessTokenRequest
|
||||
*/
|
||||
export const CreateUserAccessTokenRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.CreateUserAccessTokenRequest",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "user_access_token", kind: "message", T: UserAccessToken },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.CreateUserAccessTokenResponse
|
||||
*/
|
||||
export const CreateUserAccessTokenResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.CreateUserAccessTokenResponse",
|
||||
() => [
|
||||
{ no: 1, name: "access_token", kind: "message", T: UserAccessToken },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.DeleteUserAccessTokenRequest
|
||||
*/
|
||||
export const DeleteUserAccessTokenRequest = proto3.makeMessageType(
|
||||
"slash.api.v2.DeleteUserAccessTokenRequest",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "access_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.DeleteUserAccessTokenResponse
|
||||
*/
|
||||
export const DeleteUserAccessTokenResponse = proto3.makeMessageType(
|
||||
"slash.api.v2.DeleteUserAccessTokenResponse",
|
||||
[],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.api.v2.UserAccessToken
|
||||
*/
|
||||
export const UserAccessToken = proto3.makeMessageType(
|
||||
"slash.api.v2.UserAccessToken",
|
||||
() => [
|
||||
{ no: 1, name: "access_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 3, name: "issued_at", kind: "message", T: Timestamp },
|
||||
{ no: 4, name: "expires_at", kind: "message", T: Timestamp },
|
||||
],
|
||||
);
|
||||
|
25
web/src/types/proto/store/common_pb.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/common.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.RowStatus
|
||||
*/
|
||||
export declare enum RowStatus {
|
||||
/**
|
||||
* @generated from enum value: ROW_STATUS_UNSPECIFIED = 0;
|
||||
*/
|
||||
ROW_STATUS_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: NORMAL = 1;
|
||||
*/
|
||||
NORMAL = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: ARCHIVED = 2;
|
||||
*/
|
||||
ARCHIVED = 2,
|
||||
}
|
||||
|
19
web/src/types/proto/store/common_pb.js
Normal file
@ -0,0 +1,19 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/common.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.RowStatus
|
||||
*/
|
||||
export const RowStatus = proto3.makeEnum(
|
||||
"slash.store.RowStatus",
|
||||
[
|
||||
{no: 0, name: "ROW_STATUS_UNSPECIFIED"},
|
||||
{no: 1, name: "NORMAL"},
|
||||
{no: 2, name: "ARCHIVED"},
|
||||
],
|
||||
);
|
||||
|
147
web/src/types/proto/store/shortcut_pb.d.ts
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/shortcut.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
|
||||
import { Message, proto3 } from "@bufbuild/protobuf";
|
||||
import type { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.Visibility
|
||||
*/
|
||||
export declare enum Visibility {
|
||||
/**
|
||||
* @generated from enum value: VISIBILITY_UNSPECIFIED = 0;
|
||||
*/
|
||||
VISIBILITY_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: PRIVATE = 1;
|
||||
*/
|
||||
PRIVATE = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: WORKSPACE = 2;
|
||||
*/
|
||||
WORKSPACE = 2,
|
||||
|
||||
/**
|
||||
* @generated from enum value: PUBLIC = 3;
|
||||
*/
|
||||
PUBLIC = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.Shortcut
|
||||
*/
|
||||
export declare class Shortcut extends Message<Shortcut> {
|
||||
/**
|
||||
* @generated from field: int32 id = 1;
|
||||
*/
|
||||
id: number;
|
||||
|
||||
/**
|
||||
* @generated from field: int32 creator_id = 2;
|
||||
*/
|
||||
creatorId: number;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 created_ts = 3;
|
||||
*/
|
||||
createdTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 updated_ts = 4;
|
||||
*/
|
||||
updatedTs: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.store.RowStatus row_status = 5;
|
||||
*/
|
||||
rowStatus: RowStatus;
|
||||
|
||||
/**
|
||||
* @generated from field: string name = 6;
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string link = 7;
|
||||
*/
|
||||
link: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string title = 8;
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* @generated from field: repeated string tags = 9;
|
||||
*/
|
||||
tags: string[];
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 10;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.store.Visibility visibility = 11;
|
||||
*/
|
||||
visibility: Visibility;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.store.OpenGraphMetadata og_metadata = 12;
|
||||
*/
|
||||
ogMetadata?: OpenGraphMetadata;
|
||||
|
||||
constructor(data?: PartialMessage<Shortcut>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.Shortcut";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): Shortcut;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): Shortcut;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): Shortcut;
|
||||
|
||||
static equals(a: Shortcut | PlainMessage<Shortcut> | undefined, b: Shortcut | PlainMessage<Shortcut> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.OpenGraphMetadata
|
||||
*/
|
||||
export declare class OpenGraphMetadata extends Message<OpenGraphMetadata> {
|
||||
/**
|
||||
* @generated from field: string title = 1;
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 2;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string image = 3;
|
||||
*/
|
||||
image: string;
|
||||
|
||||
constructor(data?: PartialMessage<OpenGraphMetadata>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.OpenGraphMetadata";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): OpenGraphMetadata;
|
||||
|
||||
static equals(a: OpenGraphMetadata | PlainMessage<OpenGraphMetadata> | undefined, b: OpenGraphMetadata | PlainMessage<OpenGraphMetadata> | undefined): boolean;
|
||||
}
|
||||
|
54
web/src/types/proto/store/shortcut_pb.js
Normal file
@ -0,0 +1,54 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/shortcut.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
import { RowStatus } from "./common_pb.js";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.Visibility
|
||||
*/
|
||||
export const Visibility = proto3.makeEnum(
|
||||
"slash.store.Visibility",
|
||||
[
|
||||
{no: 0, name: "VISIBILITY_UNSPECIFIED"},
|
||||
{no: 1, name: "PRIVATE"},
|
||||
{no: 2, name: "WORKSPACE"},
|
||||
{no: 3, name: "PUBLIC"},
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.Shortcut
|
||||
*/
|
||||
export const Shortcut = proto3.makeMessageType(
|
||||
"slash.store.Shortcut",
|
||||
() => [
|
||||
{ no: 1, name: "id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "creator_id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 3, name: "created_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 4, name: "updated_ts", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
||||
{ no: 5, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) },
|
||||
{ no: 6, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 7, name: "link", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 8, name: "title", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 9, name: "tags", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
||||
{ no: 10, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 11, name: "visibility", kind: "enum", T: proto3.getEnumType(Visibility) },
|
||||
{ no: 12, name: "og_metadata", kind: "message", T: OpenGraphMetadata },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.OpenGraphMetadata
|
||||
*/
|
||||
export const OpenGraphMetadata = proto3.makeMessageType(
|
||||
"slash.store.OpenGraphMetadata",
|
||||
() => [
|
||||
{ no: 1, name: "title", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 3, name: "image", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
);
|
||||
|
116
web/src/types/proto/store/user_setting_pb.d.ts
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/user_setting.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
|
||||
import { Message, proto3 } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.UserSettingKey
|
||||
*/
|
||||
export declare enum UserSettingKey {
|
||||
/**
|
||||
* @generated from enum value: USER_SETTING_KEY_UNSPECIFIED = 0;
|
||||
*/
|
||||
USER_SETTING_KEY_UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: USER_SETTING_ACCESS_TOKENS = 1;
|
||||
*/
|
||||
USER_SETTING_ACCESS_TOKENS = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.UserSetting
|
||||
*/
|
||||
export declare class UserSetting extends Message<UserSetting> {
|
||||
/**
|
||||
* @generated from field: int32 user_id = 1;
|
||||
*/
|
||||
userId: number;
|
||||
|
||||
/**
|
||||
* @generated from field: slash.store.UserSettingKey key = 2;
|
||||
*/
|
||||
key: UserSettingKey;
|
||||
|
||||
/**
|
||||
* @generated from oneof slash.store.UserSetting.value
|
||||
*/
|
||||
value: {
|
||||
/**
|
||||
* @generated from field: slash.store.AccessTokensUserSetting access_tokens_user_setting = 3;
|
||||
*/
|
||||
value: AccessTokensUserSetting;
|
||||
case: "accessTokensUserSetting";
|
||||
} | { case: undefined; value?: undefined };
|
||||
|
||||
constructor(data?: PartialMessage<UserSetting>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.UserSetting";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): UserSetting;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): UserSetting;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): UserSetting;
|
||||
|
||||
static equals(a: UserSetting | PlainMessage<UserSetting> | undefined, b: UserSetting | PlainMessage<UserSetting> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.AccessTokensUserSetting
|
||||
*/
|
||||
export declare class AccessTokensUserSetting extends Message<AccessTokensUserSetting> {
|
||||
/**
|
||||
* @generated from field: repeated slash.store.AccessTokensUserSetting.AccessToken access_tokens = 1;
|
||||
*/
|
||||
accessTokens: AccessTokensUserSetting_AccessToken[];
|
||||
|
||||
constructor(data?: PartialMessage<AccessTokensUserSetting>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.AccessTokensUserSetting";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AccessTokensUserSetting;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AccessTokensUserSetting;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AccessTokensUserSetting;
|
||||
|
||||
static equals(a: AccessTokensUserSetting | PlainMessage<AccessTokensUserSetting> | undefined, b: AccessTokensUserSetting | PlainMessage<AccessTokensUserSetting> | undefined): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.AccessTokensUserSetting.AccessToken
|
||||
*/
|
||||
export declare class AccessTokensUserSetting_AccessToken extends Message<AccessTokensUserSetting_AccessToken> {
|
||||
/**
|
||||
* @generated from field: string access_token = 1;
|
||||
*/
|
||||
accessToken: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string description = 2;
|
||||
*/
|
||||
description: string;
|
||||
|
||||
constructor(data?: PartialMessage<AccessTokensUserSetting_AccessToken>);
|
||||
|
||||
static readonly runtime: typeof proto3;
|
||||
static readonly typeName = "slash.store.AccessTokensUserSetting.AccessToken";
|
||||
static readonly fields: FieldList;
|
||||
|
||||
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): AccessTokensUserSetting_AccessToken;
|
||||
|
||||
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): AccessTokensUserSetting_AccessToken;
|
||||
|
||||
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): AccessTokensUserSetting_AccessToken;
|
||||
|
||||
static equals(a: AccessTokensUserSetting_AccessToken | PlainMessage<AccessTokensUserSetting_AccessToken> | undefined, b: AccessTokensUserSetting_AccessToken | PlainMessage<AccessTokensUserSetting_AccessToken> | undefined): boolean;
|
||||
}
|
||||
|
52
web/src/types/proto/store/user_setting_pb.js
Normal file
@ -0,0 +1,52 @@
|
||||
// @generated by protoc-gen-es v1.3.0
|
||||
// @generated from file store/user_setting.proto (package slash.store, syntax proto3)
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { proto3 } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* @generated from enum slash.store.UserSettingKey
|
||||
*/
|
||||
export const UserSettingKey = proto3.makeEnum(
|
||||
"slash.store.UserSettingKey",
|
||||
[
|
||||
{no: 0, name: "USER_SETTING_KEY_UNSPECIFIED"},
|
||||
{no: 1, name: "USER_SETTING_ACCESS_TOKENS"},
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.UserSetting
|
||||
*/
|
||||
export const UserSetting = proto3.makeMessageType(
|
||||
"slash.store.UserSetting",
|
||||
() => [
|
||||
{ no: 1, name: "user_id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
|
||||
{ no: 2, name: "key", kind: "enum", T: proto3.getEnumType(UserSettingKey) },
|
||||
{ no: 3, name: "access_tokens_user_setting", kind: "message", T: AccessTokensUserSetting, oneof: "value" },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.AccessTokensUserSetting
|
||||
*/
|
||||
export const AccessTokensUserSetting = proto3.makeMessageType(
|
||||
"slash.store.AccessTokensUserSetting",
|
||||
() => [
|
||||
{ no: 1, name: "access_tokens", kind: "message", T: AccessTokensUserSetting_AccessToken, repeated: true },
|
||||
],
|
||||
);
|
||||
|
||||
/**
|
||||
* @generated from message slash.store.AccessTokensUserSetting.AccessToken
|
||||
*/
|
||||
export const AccessTokensUserSetting_AccessToken = proto3.makeMessageType(
|
||||
"slash.store.AccessTokensUserSetting.AccessToken",
|
||||
() => [
|
||||
{ no: 1, name: "access_token", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
{ no: 2, name: "description", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
||||
],
|
||||
{localName: "AccessTokensUserSetting_AccessToken"},
|
||||
);
|
||||
|