chore: remove openid field from user

This commit is contained in:
Steven 2023-09-14 22:57:27 +08:00
parent 42bd9b194b
commit 33d9c13b7e
31 changed files with 298 additions and 819 deletions

View File

@ -1,6 +1,7 @@
package v1
import (
"context"
"encoding/json"
"fmt"
"net/http"
@ -13,6 +14,7 @@ import (
"github.com/usememos/memos/common/util"
"github.com/usememos/memos/plugin/idp"
"github.com/usememos/memos/plugin/idp/oauth2"
storepb "github.com/usememos/memos/proto/gen/store"
"github.com/usememos/memos/store"
"golang.org/x/crypto/bcrypt"
)
@ -100,6 +102,9 @@ func (s *APIV1Service) SignIn(c echo.Context) error {
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)
}
if err := s.createAuthSignInActivity(c, user); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create activity").SetInternal(err)
}
@ -198,7 +203,6 @@ func (s *APIV1Service) SignInSSO(c echo.Context) error {
Role: store.RoleUser,
Nickname: userInfo.DisplayName,
Email: userInfo.Email,
OpenID: util.GenUUID(),
}
password, err := util.RandomString(20)
if err != nil {
@ -222,6 +226,9 @@ func (s *APIV1Service) SignInSSO(c echo.Context) error {
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)
}
if err := s.createAuthSignInActivity(c, user); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create activity").SetInternal(err)
}
@ -277,7 +284,6 @@ func (s *APIV1Service) SignUp(c echo.Context) error {
// The new signup user should be normal user by default.
Role: store.RoleUser,
Nickname: signup.Username,
OpenID: util.GenUUID(),
}
if len(existedHostUsers) == 0 {
// Change the default role to host if there is no host user.
@ -316,6 +322,9 @@ func (s *APIV1Service) SignUp(c echo.Context) error {
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)
}
if err := s.createAuthSignUpActivity(c, user); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create activity").SetInternal(err)
}
@ -325,6 +334,30 @@ func (s *APIV1Service) SignUp(c echo.Context) error {
return c.JSON(http.StatusOK, userMessage)
}
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.UpsertUserSettingV1(ctx, &storepb.UserSetting{
UserId: user.ID,
Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS,
Value: &storepb.UserSetting_AccessTokens{
AccessTokens: &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
}
func (s *APIV1Service) createAuthSignInActivity(c echo.Context, user *store.User) error {
ctx := c.Request().Context()
payload := ActivityUserAuthSignInPayload{

View File

@ -209,11 +209,6 @@ const docTemplate = `{
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -256,11 +251,6 @@ const docTemplate = `{
},
"/api/v1/idp/{idpId}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -302,11 +292,6 @@ const docTemplate = `{
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -345,11 +330,6 @@ const docTemplate = `{
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -399,11 +379,6 @@ const docTemplate = `{
},
"/api/v1/memo": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -484,11 +459,6 @@ const docTemplate = `{
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Visibility can be PUBLIC, PROTECTED or PRIVATE\n*You should omit fields to use their default values",
"consumes": [
"application/json"
@ -535,11 +505,6 @@ const docTemplate = `{
},
"/api/v1/memo/all": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "This should also list protected memos if the user is logged in\nAuthentication is optional",
"produces": [
"application/json"
@ -667,11 +632,6 @@ const docTemplate = `{
}
},
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -710,11 +670,6 @@ const docTemplate = `{
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Visibility can be PUBLIC, PROTECTED or PRIVATE\n*You should omit fields to use their default values",
"consumes": [
"application/json"
@ -768,11 +723,6 @@ const docTemplate = `{
},
"/api/v1/memo/{memoId}/organizer": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1004,11 +954,6 @@ const docTemplate = `{
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1058,11 +1003,6 @@ const docTemplate = `{
},
"/api/v1/memo/{memoId}/resource/{resourceId}": {
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1129,11 +1069,6 @@ const docTemplate = `{
},
"/api/v1/resource": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1174,11 +1109,6 @@ const docTemplate = `{
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1221,11 +1151,6 @@ const docTemplate = `{
},
"/api/v1/resource/blob": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"multipart/form-data"
],
@ -1266,11 +1191,6 @@ const docTemplate = `{
},
"/api/v1/resource/{resourceId}": {
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1309,11 +1229,6 @@ const docTemplate = `{
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1388,11 +1303,6 @@ const docTemplate = `{
},
"/api/v1/storage": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1419,11 +1329,6 @@ const docTemplate = `{
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1466,11 +1371,6 @@ const docTemplate = `{
},
"/api/v1/storage/{storageId}": {
"delete": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1506,11 +1406,6 @@ const docTemplate = `{
}
},
"patch": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1557,11 +1452,6 @@ const docTemplate = `{
},
"/api/v1/system/setting": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1588,11 +1478,6 @@ const docTemplate = `{
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1638,11 +1523,6 @@ const docTemplate = `{
},
"/api/v1/system/vacuum": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1668,11 +1548,6 @@ const docTemplate = `{
},
"/api/v1/tag": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1699,11 +1574,6 @@ const docTemplate = `{
}
},
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1746,11 +1616,6 @@ const docTemplate = `{
},
"/api/v1/tag/delete": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1793,11 +1658,6 @@ const docTemplate = `{
},
"/api/v1/tag/suggestion": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1894,11 +1754,6 @@ const docTemplate = `{
},
"/api/v1/user/me": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"produces": [
"application/json"
],
@ -1958,11 +1813,6 @@ const docTemplate = `{
},
"/api/v1/user/setting": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"consumes": [
"application/json"
],
@ -1988,7 +1838,7 @@ const docTemplate = `{
"200": {
"description": "Created user setting",
"schema": {
"$ref": "#/definitions/store.UserSetting"
"$ref": "#/definitions/github_com_usememos_memos_store.UserSetting"
}
},
"400": {
@ -2300,6 +2150,20 @@ const docTemplate = `{
}
}
},
"github_com_usememos_memos_store.UserSetting": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"userID": {
"type": "integer"
},
"value": {
"type": "string"
}
}
},
"profile.Profile": {
"type": "object",
"properties": {
@ -2582,9 +2446,6 @@ const docTemplate = `{
"nickname": {
"type": "string"
},
"openID": {
"type": "string"
},
"passwordHash": {
"type": "string"
},
@ -2608,20 +2469,6 @@ const docTemplate = `{
}
}
},
"store.UserSetting": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"userID": {
"type": "integer"
},
"value": {
"type": "string"
}
}
},
"store.Visibility": {
"type": "string",
"enum": [
@ -3205,9 +3052,6 @@ const docTemplate = `{
"password": {
"type": "string"
},
"resetOpenId": {
"type": "boolean"
},
"rowStatus": {
"$ref": "#/definitions/v1.RowStatus"
},
@ -3297,9 +3141,6 @@ const docTemplate = `{
"nickname": {
"type": "string"
},
"openId": {
"type": "string"
},
"role": {
"$ref": "#/definitions/v1.Role"
},
@ -3369,16 +3210,8 @@ const docTemplate = `{
]
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"description": "Insert your Open ID API Key here.",
"type": "apiKey",
"name": "openId",
"in": "query"
}
},
"externalDocs": {
"description": "Find out more about Memos",
"description": "Find out more about Memos.",
"url": "https://usememos.com/"
}
}`

View File

@ -124,7 +124,6 @@ func (s *APIV1Service) GetIdentityProviderList(c echo.Context) error {
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 400 {object} nil "Malformatted post identity provider request"
// @Failure 500 {object} nil "Failed to find user | Failed to create identity provider"
// @Security ApiKeyAuth
// @Router /api/v1/idp [POST]
func (s *APIV1Service) CreateIdentityProvider(c echo.Context) error {
ctx := c.Request().Context()
@ -172,7 +171,6 @@ func (s *APIV1Service) CreateIdentityProvider(c echo.Context) error {
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 404 {object} nil "Identity provider not found"
// @Failure 500 {object} nil "Failed to find identity provider list | Failed to find user"
// @Security ApiKeyAuth
// @Router /api/v1/idp/{idpId} [GET]
func (s *APIV1Service) GetIdentityProvider(c echo.Context) error {
ctx := c.Request().Context()
@ -219,7 +217,6 @@ func (s *APIV1Service) GetIdentityProvider(c echo.Context) error {
// @Failure 400 {object} nil "ID is not a number: %s | Malformatted patch identity provider request"
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 500 {object} nil "Failed to find user | Failed to patch identity provider"
// @Security ApiKeyAuth
// @Router /api/v1/idp/{idpId} [DELETE]
func (s *APIV1Service) DeleteIdentityProvider(c echo.Context) error {
ctx := c.Request().Context()
@ -261,7 +258,6 @@ func (s *APIV1Service) DeleteIdentityProvider(c echo.Context) error {
// @Failure 400 {object} nil "ID is not a number: %s | Malformatted patch identity provider request"
// @Failure 401 {object} nil "Missing user in session | Unauthorized
// @Failure 500 {object} nil "Failed to find user | Failed to patch identity provider"
// @Security ApiKeyAuth
// @Router /api/v1/idp/{idpId} [PATCH]
func (s *APIV1Service) UpdateIdentityProvider(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -128,7 +128,6 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
}
func (s *APIV1Service) defaultAuthSkipper(c echo.Context) bool {
ctx := c.Request().Context()
path := c.Path()
// Skip auth.
@ -136,21 +135,5 @@ func (s *APIV1Service) defaultAuthSkipper(c echo.Context) bool {
return true
}
// If there is openId in query string and related user is found, then skip auth.
openID := c.QueryParam("openId")
if openID != "" {
user, err := s.Store.GetUser(ctx, &store.FindUser{
OpenID: &openID,
})
if err != nil {
return false
}
if user != nil {
// Stores userID into context.
c.Set(userIDContextKey, user.ID)
return true
}
}
return false
}

View File

@ -139,7 +139,6 @@ func (s *APIV1Service) registerMemoRoutes(g *echo.Group) {
// @Success 200 {object} []store.Memo "Memo list"
// @Failure 400 {object} nil "Missing user to find memo"
// @Failure 500 {object} nil "Failed to get memo display with updated ts setting value | Failed to fetch memo list | Failed to compose memo response"
// @Security ApiKeyAuth
// @Router /api/v1/memo [GET]
func (s *APIV1Service) GetMemoList(c echo.Context) error {
ctx := c.Request().Context()
@ -239,7 +238,6 @@ func (s *APIV1Service) GetMemoList(c echo.Context) error {
// @Failure 401 {object} nil "Missing user in session"
// @Failure 404 {object} nil "User not found | Memo not found: %d"
// @Failure 500 {object} nil "Failed to find user setting | Failed to unmarshal user setting value | Failed to find system setting | Failed to unmarshal system setting | Failed to find user | Failed to create memo | Failed to create activity | Failed to upsert memo resource | Failed to upsert memo relation | Failed to compose memo | Failed to compose memo response"
// @Security ApiKeyAuth
// @Router /api/v1/memo [POST]
//
// NOTES:
@ -398,7 +396,6 @@ func (s *APIV1Service) CreateMemo(c echo.Context) error {
// @Param offset query int false "Offset"
// @Success 200 {object} []store.Memo "Memo list"
// @Failure 500 {object} nil "Failed to get memo display with updated ts setting value | Failed to fetch all memo list | Failed to compose memo response"
// @Security ApiKeyAuth
// @Router /api/v1/memo/all [GET]
//
// NOTES:
@ -575,7 +572,6 @@ func (s *APIV1Service) GetMemo(c echo.Context) error {
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 404 {object} nil "Memo not found: %d"
// @Failure 500 {object} nil "Failed to find memo | Failed to delete memo ID: %v"
// @Security ApiKeyAuth
// @Router /api/v1/memo/{memoId} [DELETE]
func (s *APIV1Service) DeleteMemo(c echo.Context) error {
ctx := c.Request().Context()
@ -624,7 +620,6 @@ func (s *APIV1Service) DeleteMemo(c echo.Context) error {
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 404 {object} nil "Memo not found: %d"
// @Failure 500 {object} nil "Failed to find memo | Failed to patch memo | Failed to upsert memo resource | Failed to delete memo resource | Failed to compose memo response"
// @Security ApiKeyAuth
// @Router /api/v1/memo/{memoId} [PATCH]
//
// NOTES:

View File

@ -37,7 +37,6 @@ func (s *APIV1Service) registerMemoOrganizerRoutes(g *echo.Group) {
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 404 {object} nil "Memo not found: %v"
// @Failure 500 {object} nil "Failed to find memo | Failed to upsert memo organizer | Failed to find memo by ID: %v | Failed to compose memo response"
// @Security ApiKeyAuth
// @Router /api/v1/memo/{memoId}/organizer [POST]
func (s *APIV1Service) CreateMemoOrganizer(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -82,7 +82,6 @@ func (s *APIV1Service) GetMemoResourceList(c echo.Context) error {
// @Failure 400 {object} nil "ID is not a number: %s | Malformatted post memo resource request | Resource not found"
// @Failure 401 {object} nil "Missing user in session | Unauthorized to bind this resource"
// @Failure 500 {object} nil "Failed to fetch resource | Failed to upsert memo resource"
// @Security ApiKeyAuth
// @Router /api/v1/memo/{memoId}/resource [POST]
//
// NOTES:
@ -140,7 +139,6 @@ func (s *APIV1Service) BindMemoResource(c echo.Context) error {
// @Failure 400 {object} nil "Memo ID is not a number: %s | Resource ID is not a number: %s | Memo not found"
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 500 {object} nil "Failed to find memo | Failed to fetch resource list"
// @Security ApiKeyAuth
// @Router /api/v1/memo/{memoId}/resource/{resourceId} [DELETE]
func (s *APIV1Service) UnbindMemoResource(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -100,7 +100,6 @@ func (s *APIV1Service) registerResourcePublicRoutes(g *echo.Group) {
// @Success 200 {object} []store.Resource "Resource list"
// @Failure 401 {object} nil "Missing user in session"
// @Failure 500 {object} nil "Failed to fetch resource list"
// @Security ApiKeyAuth
// @Router /api/v1/resource [GET]
func (s *APIV1Service) GetResourceList(c echo.Context) error {
ctx := c.Request().Context()
@ -140,7 +139,6 @@ func (s *APIV1Service) GetResourceList(c echo.Context) error {
// @Failure 400 {object} nil "Malformatted post resource request | Invalid external link | Invalid external link scheme | Failed to request %s | Failed to read %s | Failed to read mime from %s"
// @Failure 401 {object} nil "Missing user in session"
// @Failure 500 {object} nil "Failed to save resource | Failed to create resource | Failed to create activity"
// @Security ApiKeyAuth
// @Router /api/v1/resource [POST]
func (s *APIV1Service) CreateResource(c echo.Context) error {
ctx := c.Request().Context()
@ -192,7 +190,6 @@ func (s *APIV1Service) CreateResource(c echo.Context) error {
// @Failure 400 {object} nil "Upload file not found | File size exceeds allowed limit of %d MiB | Failed to parse upload data"
// @Failure 401 {object} nil "Missing user in session"
// @Failure 500 {object} nil "Failed to get uploading file | Failed to open file | Failed to save resource | Failed to create resource | Failed to create activity"
// @Security ApiKeyAuth
// @Router /api/v1/resource/blob [POST]
func (s *APIV1Service) UploadResource(c echo.Context) error {
ctx := c.Request().Context()
@ -265,7 +262,6 @@ func (s *APIV1Service) UploadResource(c echo.Context) error {
// @Failure 401 {object} nil "Missing user in session"
// @Failure 404 {object} nil "Resource not found: %d"
// @Failure 500 {object} nil "Failed to find resource | Failed to delete resource"
// @Security ApiKeyAuth
// @Router /api/v1/resource/{resourceId} [DELETE]
func (s *APIV1Service) DeleteResource(c echo.Context) error {
ctx := c.Request().Context()
@ -322,7 +318,6 @@ func (s *APIV1Service) DeleteResource(c echo.Context) error {
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 404 {object} nil "Resource not found: %d"
// @Failure 500 {object} nil "Failed to find resource | Failed to patch resource"
// @Security ApiKeyAuth
// @Router /api/v1/resource/{resourceId} [PATCH]
func (s *APIV1Service) UpdateResource(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -77,7 +77,6 @@ func (s *APIV1Service) registerStorageRoutes(g *echo.Group) {
// @Success 200 {object} []store.Storage "List of storages"
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 500 {object} nil "Failed to find user | Failed to convert storage"
// @Security ApiKeyAuth
// @Router /api/v1/storage [GET]
func (s *APIV1Service) GetStorageList(c echo.Context) error {
ctx := c.Request().Context()
@ -124,7 +123,6 @@ func (s *APIV1Service) GetStorageList(c echo.Context) error {
// @Failure 400 {object} nil "Malformatted post storage request"
// @Failure 401 {object} nil "Missing user in session"
// @Failure 500 {object} nil "Failed to find user | Failed to create storage | Failed to convert storage"
// @Security ApiKeyAuth
// @Router /api/v1/storage [POST]
func (s *APIV1Service) CreateStorage(c echo.Context) error {
ctx := c.Request().Context()
@ -182,7 +180,6 @@ func (s *APIV1Service) CreateStorage(c echo.Context) error {
// @Failure 400 {object} nil "ID is not a number: %s | Storage service %d is using"
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 500 {object} nil "Failed to find user | Failed to find storage | Failed to unmarshal storage service id | Failed to delete storage"
// @Security ApiKeyAuth
// @Router /api/v1/storage/{storageId} [DELETE]
//
// NOTES:
@ -241,7 +238,6 @@ func (s *APIV1Service) DeleteStorage(c echo.Context) error {
// @Failure 400 {object} nil "ID is not a number: %s | Malformatted patch storage request | Malformatted post storage request"
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 500 {object} nil "Failed to find user | Failed to patch storage | Failed to convert storage"
// @Security ApiKeyAuth
// @Router /api/v1/storage/{storageId} [PATCH]
func (s *APIV1Service) UpdateStorage(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -9,6 +9,15 @@ definitions:
title:
type: string
type: object
github_com_usememos_memos_store.UserSetting:
properties:
key:
type: string
userID:
type: integer
value:
type: string
type: object
profile.Profile:
properties:
mode:
@ -197,8 +206,6 @@ definitions:
type: integer
nickname:
type: string
openID:
type: string
passwordHash:
type: string
role:
@ -213,15 +220,6 @@ definitions:
description: Domain specific fields
type: string
type: object
store.UserSetting:
properties:
key:
type: string
userID:
type: integer
value:
type: string
type: object
store.Visibility:
enum:
- PUBLIC
@ -624,8 +622,6 @@ definitions:
type: string
password:
type: string
resetOpenId:
type: boolean
rowStatus:
$ref: '#/definitions/v1.RowStatus'
username:
@ -683,8 +679,6 @@ definitions:
type: integer
nickname:
type: string
openId:
type: string
role:
$ref: '#/definitions/v1.Role'
rowStatus:
@ -733,7 +727,7 @@ definitions:
- Protected
- Private
externalDocs:
description: Find out more about Memos
description: Find out more about Memos.
url: https://usememos.com/
info:
contact:
@ -899,8 +893,6 @@ paths:
description: Missing user in session | Unauthorized
"500":
description: Failed to find user | Failed to create identity provider
security:
- ApiKeyAuth: []
summary: Create Identity Provider
tags:
- idp
@ -928,8 +920,6 @@ paths:
description: Missing user in session | Unauthorized
"500":
description: Failed to find user | Failed to patch identity provider
security:
- ApiKeyAuth: []
summary: Delete an identity provider by ID
tags:
- idp
@ -957,8 +947,6 @@ paths:
description: Identity provider not found
"500":
description: Failed to find identity provider list | Failed to find user
security:
- ApiKeyAuth: []
summary: Get an identity provider by ID
tags:
- idp
@ -991,8 +979,6 @@ paths:
description: Missing user in session | Unauthorized
"500":
description: Failed to find user | Failed to patch identity provider
security:
- ApiKeyAuth: []
summary: Update an identity provider by ID
tags:
- idp
@ -1048,8 +1034,6 @@ paths:
"500":
description: Failed to get memo display with updated ts setting value |
Failed to fetch memo list | Failed to compose memo response
security:
- ApiKeyAuth: []
summary: Get a list of memos matching optional filters
tags:
- memo
@ -1086,8 +1070,6 @@ paths:
| Failed to find user | Failed to create memo | Failed to create activity
| Failed to upsert memo resource | Failed to upsert memo relation | Failed
to compose memo | Failed to compose memo response
security:
- ApiKeyAuth: []
summary: Create a memo
tags:
- memo
@ -1114,8 +1096,6 @@ paths:
description: 'Memo not found: %d'
"500":
description: 'Failed to find memo | Failed to delete memo ID: %v'
security:
- ApiKeyAuth: []
summary: Delete memo by ID
tags:
- memo
@ -1185,8 +1165,6 @@ paths:
description: Failed to find memo | Failed to patch memo | Failed to upsert
memo resource | Failed to delete memo resource | Failed to compose memo
response
security:
- ApiKeyAuth: []
summary: Update a memo
tags:
- memo
@ -1223,8 +1201,6 @@ paths:
"500":
description: 'Failed to find memo | Failed to upsert memo organizer | Failed
to find memo by ID: %v | Failed to compose memo response'
security:
- ApiKeyAuth: []
summary: Organize memo (pin/unpin)
tags:
- memo-organizer
@ -1378,8 +1354,6 @@ paths:
description: Missing user in session | Unauthorized to bind this resource
"500":
description: Failed to fetch resource | Failed to upsert memo resource
security:
- ApiKeyAuth: []
summary: Bind resource to memo
tags:
- memo-resource
@ -1413,8 +1387,6 @@ paths:
description: Missing user in session | Unauthorized
"500":
description: Failed to find memo | Failed to fetch resource list
security:
- ApiKeyAuth: []
summary: Unbind resource from memo
tags:
- memo-resource
@ -1444,8 +1416,6 @@ paths:
"500":
description: Failed to get memo display with updated ts setting value |
Failed to fetch all memo list | Failed to compose memo response
security:
- ApiKeyAuth: []
summary: Get a list of public memos matching optional filters
tags:
- memo
@ -1514,8 +1484,6 @@ paths:
description: Missing user in session
"500":
description: Failed to fetch resource list
security:
- ApiKeyAuth: []
summary: Get a list of resources
tags:
- resource
@ -1545,8 +1513,6 @@ paths:
"500":
description: Failed to save resource | Failed to create resource | Failed
to create activity
security:
- ApiKeyAuth: []
summary: Create resource
tags:
- resource
@ -1573,8 +1539,6 @@ paths:
description: 'Resource not found: %d'
"500":
description: Failed to find resource | Failed to delete resource
security:
- ApiKeyAuth: []
summary: Delete a resource
tags:
- resource
@ -1606,8 +1570,6 @@ paths:
description: 'Resource not found: %d'
"500":
description: Failed to find resource | Failed to patch resource
security:
- ApiKeyAuth: []
summary: Update a resource
tags:
- resource
@ -1636,8 +1598,6 @@ paths:
"500":
description: Failed to get uploading file | Failed to open file | Failed
to save resource | Failed to create resource | Failed to create activity
security:
- ApiKeyAuth: []
summary: Upload resource
tags:
- resource
@ -1673,8 +1633,6 @@ paths:
description: Missing user in session | Unauthorized
"500":
description: Failed to find user | Failed to convert storage
security:
- ApiKeyAuth: []
summary: Get a list of storages
tags:
- storage
@ -1702,8 +1660,6 @@ paths:
"500":
description: Failed to find user | Failed to create storage | Failed to
convert storage
security:
- ApiKeyAuth: []
summary: Create storage
tags:
- storage
@ -1729,8 +1685,6 @@ paths:
"500":
description: Failed to find user | Failed to find storage | Failed to unmarshal
storage service id | Failed to delete storage
security:
- ApiKeyAuth: []
summary: Delete a storage
tags:
- storage
@ -1762,8 +1716,6 @@ paths:
"500":
description: Failed to find user | Failed to patch storage | Failed to convert
storage
security:
- ApiKeyAuth: []
summary: Update a storage
tags:
- storage
@ -1782,8 +1734,6 @@ paths:
description: Missing user in session | Unauthorized
"500":
description: Failed to find user | Failed to find system setting list
security:
- ApiKeyAuth: []
summary: Get a list of system settings
tags:
- system-setting
@ -1812,8 +1762,6 @@ paths:
description: Cannot disable passwords if no SSO identity provider is configured.
"500":
description: Failed to find user | Failed to upsert system setting
security:
- ApiKeyAuth: []
summary: Create system setting
tags:
- system-setting
@ -1830,8 +1778,6 @@ paths:
description: Missing user in session | Unauthorized
"500":
description: Failed to find user | Failed to ExecVacuum database
security:
- ApiKeyAuth: []
summary: Vacuum the database
tags:
- system
@ -1850,8 +1796,6 @@ paths:
description: Missing user id to find tag
"500":
description: Failed to find tag list
security:
- ApiKeyAuth: []
summary: Get a list of tags
tags:
- tag
@ -1878,8 +1822,6 @@ paths:
description: Missing user in session
"500":
description: Failed to upsert tag | Failed to create activity
security:
- ApiKeyAuth: []
summary: Create a tag
tags:
- tag
@ -1907,8 +1849,6 @@ paths:
description: Missing user in session
"500":
description: 'Failed to delete tag name: %v'
security:
- ApiKeyAuth: []
summary: Delete a tag
tags:
- tag
@ -1927,8 +1867,6 @@ paths:
description: Missing user session
"500":
description: Failed to find memo list | Failed to find tag list
security:
- ApiKeyAuth: []
summary: Get a list of tags suggested from other memos contents
tags:
- tag
@ -2073,8 +2011,6 @@ paths:
description: Missing auth session
"500":
description: Failed to find user | Failed to find userSettingList
security:
- ApiKeyAuth: []
summary: Get current user
tags:
- user
@ -2117,7 +2053,7 @@ paths:
"200":
description: Created user setting
schema:
$ref: '#/definitions/store.UserSetting'
$ref: '#/definitions/github_com_usememos_memos_store.UserSetting'
"400":
description: Malformatted post user setting upsert request | Invalid user
setting format
@ -2125,8 +2061,6 @@ paths:
description: Missing auth session
"500":
description: Failed to upsert user setting
security:
- ApiKeyAuth: []
summary: Upsert user setting
tags:
- user-setting
@ -2238,10 +2172,4 @@ paths:
summary: Get RSS for a user
tags:
- rss
securityDefinitions:
ApiKeyAuth:
description: Insert your Open ID API Key here.
in: query
name: openId
type: apiKey
swagger: "2.0"

View File

@ -163,7 +163,6 @@ func (s *APIV1Service) GetSystemStatus(c echo.Context) error {
// @Success 200 {boolean} true "Database vacuumed"
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 500 {object} nil "Failed to find user | Failed to ExecVacuum database"
// @Security ApiKeyAuth
// @Router /api/v1/system/vacuum [POST]
func (s *APIV1Service) ExecVacuum(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -90,7 +90,6 @@ func (s *APIV1Service) registerSystemSettingRoutes(g *echo.Group) {
// @Success 200 {object} []SystemSetting "System setting list"
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 500 {object} nil "Failed to find user | Failed to find system setting list"
// @Security ApiKeyAuth
// @Router /api/v1/system/setting [GET]
func (s *APIV1Service) GetSystemSettingList(c echo.Context) error {
ctx := c.Request().Context()
@ -133,7 +132,6 @@ func (s *APIV1Service) GetSystemSettingList(c echo.Context) error {
// @Failure 401 {object} nil "Missing user in session | Unauthorized"
// @Failure 403 {object} nil "Cannot disable passwords if no SSO identity provider is configured."
// @Failure 500 {object} nil "Failed to find user | Failed to upsert system setting"
// @Security ApiKeyAuth
// @Router /api/v1/system/setting [POST]
func (s *APIV1Service) CreateSystemSetting(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -41,7 +41,6 @@ func (s *APIV1Service) registerTagRoutes(g *echo.Group) {
// @Success 200 {object} []string "Tag list"
// @Failure 400 {object} nil "Missing user id to find tag"
// @Failure 500 {object} nil "Failed to find tag list"
// @Security ApiKeyAuth
// @Router /api/v1/tag [GET]
func (s *APIV1Service) GetTagList(c echo.Context) error {
ctx := c.Request().Context()
@ -75,7 +74,6 @@ func (s *APIV1Service) GetTagList(c echo.Context) error {
// @Failure 400 {object} nil "Malformatted post tag request | Tag name shouldn't be empty"
// @Failure 401 {object} nil "Missing user in session"
// @Failure 500 {object} nil "Failed to upsert tag | Failed to create activity"
// @Security ApiKeyAuth
// @Router /api/v1/tag [POST]
func (s *APIV1Service) CreateTag(c echo.Context) error {
ctx := c.Request().Context()
@ -117,7 +115,6 @@ func (s *APIV1Service) CreateTag(c echo.Context) error {
// @Failure 400 {object} nil "Malformatted post tag request | Tag name shouldn't be empty"
// @Failure 401 {object} nil "Missing user in session"
// @Failure 500 {object} nil "Failed to delete tag name: %v"
// @Security ApiKeyAuth
// @Router /api/v1/tag/delete [POST]
func (s *APIV1Service) DeleteTag(c echo.Context) error {
ctx := c.Request().Context()
@ -152,7 +149,6 @@ func (s *APIV1Service) DeleteTag(c echo.Context) error {
// @Success 200 {object} []string "Tag list"
// @Failure 400 {object} nil "Missing user session"
// @Failure 500 {object} nil "Failed to find memo list | Failed to find tag list"
// @Security ApiKeyAuth
// @Router /api/v1/tag/suggestion [GET]
func (s *APIV1Service) GetTagSuggestion(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -43,7 +43,6 @@ type User struct {
Email string `json:"email"`
Nickname string `json:"nickname"`
PasswordHash string `json:"-"`
OpenID string `json:"openId"`
AvatarURL string `json:"avatarUrl"`
UserSettingList []*UserSetting `json:"userSettingList"`
}
@ -57,13 +56,12 @@ type CreateUserRequest struct {
}
type UpdateUserRequest struct {
RowStatus *RowStatus `json:"rowStatus"`
Username *string `json:"username"`
Email *string `json:"email"`
Nickname *string `json:"nickname"`
Password *string `json:"password"`
ResetOpenID *bool `json:"resetOpenId"`
AvatarURL *string `json:"avatarUrl"`
RowStatus *RowStatus `json:"rowStatus"`
Username *string `json:"username"`
Email *string `json:"email"`
Nickname *string `json:"nickname"`
Password *string `json:"password"`
AvatarURL *string `json:"avatarUrl"`
}
func (s *APIV1Service) registerUserRoutes(g *echo.Group) {
@ -96,7 +94,6 @@ func (s *APIV1Service) GetUserList(c echo.Context) error {
for _, user := range list {
userMessage := convertUserFromStore(user)
// data desensitize
userMessage.OpenID = ""
userMessage.Email = ""
userMessageList = append(userMessageList, userMessage)
}
@ -158,7 +155,6 @@ func (s *APIV1Service) CreateUser(c echo.Context) error {
Email: userCreate.Email,
Nickname: userCreate.Nickname,
PasswordHash: string(passwordHash),
OpenID: util.GenUUID(),
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create user").SetInternal(err)
@ -179,7 +175,6 @@ func (s *APIV1Service) CreateUser(c echo.Context) error {
// @Success 200 {object} store.User "Current user"
// @Failure 401 {object} nil "Missing auth session"
// @Failure 500 {object} nil "Failed to find user | Failed to find userSettingList"
// @Security ApiKeyAuth
// @Router /api/v1/user/me [GET]
func (s *APIV1Service) GetCurrentUser(c echo.Context) error {
ctx := c.Request().Context()
@ -234,7 +229,6 @@ func (s *APIV1Service) GetUserByUsername(c echo.Context) error {
userMessage := convertUserFromStore(user)
// data desensitize
userMessage.OpenID = ""
userMessage.Email = ""
return c.JSON(http.StatusOK, userMessage)
}
@ -267,7 +261,6 @@ func (s *APIV1Service) GetUserByID(c echo.Context) error {
userMessage := convertUserFromStore(user)
// data desensitize
userMessage.OpenID = ""
userMessage.Email = ""
return c.JSON(http.StatusOK, userMessage)
}
@ -385,10 +378,6 @@ func (s *APIV1Service) UpdateUser(c echo.Context) error {
passwordHashStr := string(passwordHash)
userUpdate.PasswordHash = &passwordHashStr
}
if request.ResetOpenID != nil && *request.ResetOpenID {
openID := util.GenUUID()
userUpdate.OpenID = &openID
}
if request.AvatarURL != nil {
userUpdate.AvatarURL = request.AvatarURL
}
@ -508,7 +497,6 @@ func convertUserFromStore(user *store.User) *User {
Email: user.Email,
Nickname: user.Nickname,
PasswordHash: user.PasswordHash,
OpenID: user.OpenID,
AvatarURL: user.AvatarURL,
}
}

View File

@ -92,7 +92,6 @@ func (s *APIV1Service) registerUserSettingRoutes(g *echo.Group) {
// @Failure 400 {object} nil "Malformatted post user setting upsert request | Invalid user setting format"
// @Failure 401 {object} nil "Missing auth session"
// @Failure 500 {object} nil "Failed to upsert user setting"
// @Security ApiKeyAuth
// @Router /api/v1/user/setting [POST]
func (s *APIV1Service) UpsertUserSetting(c echo.Context) error {
ctx := c.Request().Context()

View File

@ -27,12 +27,7 @@ type APIV1Service struct {
// @BasePath /
//
// @externalDocs.url https://usememos.com/
// @externalDocs.description Find out more about Memos
//
// @securitydefinitions.apikey ApiKeyAuth
// @in query
// @name openId
// @description Insert your Open ID API Key here.
// @externalDocs.description Find out more about Memos.
func NewAPIV1Service(secret string, profile *profile.Profile, store *store.Store, telegramBot *telegram.Bot) *APIV1Service {
return &APIV1Service{
Secret: secret,

View File

@ -9,7 +9,6 @@ import (
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
"github.com/usememos/memos/api/auth"
"github.com/usememos/memos/common/util"
apiv2pb "github.com/usememos/memos/proto/gen/api/v2"
storepb "github.com/usememos/memos/proto/gen/store"
"github.com/usememos/memos/store"
@ -47,12 +46,6 @@ func (s *UserService) GetUser(ctx context.Context, request *apiv2pb.GetUserReque
}
userMessage := convertUserFromStore(user)
currentUser, _ := getCurrentUser(ctx, s.Store)
if currentUser == nil || currentUser.ID != user.ID {
// Data desensitization.
userMessage.OpenId = ""
}
response := &apiv2pb.GetUserResponse{
User: userMessage,
}
@ -88,9 +81,6 @@ func (s *UserService) UpdateUser(ctx context.Context, request *apiv2pb.UpdateUse
} else if path == "role" {
role := convertUserRoleToStore(request.User.Role)
update.Role = &role
} else if path == "reset_open_id" {
openID := util.GenUUID()
update.OpenID = &openID
} else if path == "password" {
passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost)
if err != nil {
@ -283,7 +273,6 @@ func convertUserFromStore(user *store.User) *apiv2pb.User {
Role: convertUserRoleFromStore(user.Role),
Email: user.Email,
Nickname: user.Nickname,
OpenId: user.OpenID,
AvatarUrl: user.AvatarURL,
}
}

View File

@ -101,7 +101,6 @@ func (s setupService) createUser(ctx context.Context, hostUsername, hostPassword
// The new signup user should be normal user by default.
Role: store.RoleHost,
Nickname: hostUsername,
OpenID: util.GenUUID(),
}
if len(userCreate.Username) < 3 {

View File

@ -9,16 +9,7 @@ API Support
**License:** [MIT License](https://github.com/usememos/memos/blob/main/LICENSE)
[Find out more about Memos](https://usememos.com/)
### Security
**ApiKeyAuth**
| apiKey | *API Key* |
| ------ | --------- |
| Description | Insert your Open ID API Key here. |
| In | query |
| Name | openId |
[Find out more about Memos.](https://usememos.com/)
---
### /api/v1/auth/signin
@ -144,12 +135,6 @@ Create Identity Provider
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find user \| Failed to create identity provider | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/idp/{idpId}
#### DELETE
@ -172,12 +157,6 @@ Delete an identity provider by ID
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find user \| Failed to patch identity provider | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### GET
##### Summary
@ -199,12 +178,6 @@ Get an identity provider by ID
| 404 | Identity provider not found | |
| 500 | Failed to find identity provider list \| Failed to find user | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### PATCH
##### Summary
@ -226,12 +199,6 @@ Update an identity provider by ID
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find user \| Failed to patch identity provider | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
---
### /api/v1/memo
@ -261,12 +228,6 @@ Get a list of memos matching optional filters
| 400 | Missing user to find memo | |
| 500 | Failed to get memo display with updated ts setting value \| Failed to fetch memo list \| Failed to compose memo response | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### POST
##### Summary
@ -293,12 +254,6 @@ Visibility can be PUBLIC, PROTECTED or PRIVATE
| 404 | User not found \| Memo not found: %d | |
| 500 | Failed to find user setting \| Failed to unmarshal user setting value \| Failed to find system setting \| Failed to unmarshal system setting \| Failed to find user \| Failed to create memo \| Failed to create activity \| Failed to upsert memo resource \| Failed to upsert memo relation \| Failed to compose memo \| Failed to compose memo response | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/memo/{memoId}
#### DELETE
@ -322,12 +277,6 @@ Delete memo by ID
| 404 | Memo not found: %d | |
| 500 | Failed to find memo \| Failed to delete memo ID: %v | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### GET
##### Summary
@ -377,12 +326,6 @@ Visibility can be PUBLIC, PROTECTED or PRIVATE
| 404 | Memo not found: %d | |
| 500 | Failed to find memo \| Failed to patch memo \| Failed to upsert memo resource \| Failed to delete memo resource \| Failed to compose memo response | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/memo/all
#### GET
@ -409,12 +352,6 @@ Authentication is optional
| 200 | Memo list | [ [store.Memo](#storememo) ] |
| 500 | Failed to get memo display with updated ts setting value \| Failed to fetch all memo list \| Failed to compose memo response | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/memo/stats
#### GET
@ -466,12 +403,6 @@ Organize memo (pin/unpin)
| 404 | Memo not found: %v | |
| 500 | Failed to find memo \| Failed to upsert memo organizer \| Failed to find memo by ID: %v \| Failed to compose memo response | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
---
### /api/v1/memo/{memoId}/relation
@ -588,12 +519,6 @@ Bind resource to memo
| 401 | Missing user in session \| Unauthorized to bind this resource | |
| 500 | Failed to fetch resource \| Failed to upsert memo resource | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/memo/{memoId}/resource/{resourceId}
#### DELETE
@ -617,12 +542,6 @@ Unbind resource from memo
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find memo \| Failed to fetch resource list | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
---
### /api/v1/ping
@ -635,20 +554,20 @@ Ping the system
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | System profile | [profile.Profile](#profileprofile) |
| 200 | If succeed to ping the system | boolean |
### /api/v1/status
#### GET
##### Summary
Get system status
Get system GetSystemStatus
##### Responses
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | System status | [v1.SystemStatus](#v1systemstatus) |
| 200 | System GetSystemStatus | [v1.SystemStatus](#v1systemstatus) |
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find host user \| Failed to find system setting list \| Failed to unmarshal system setting customized profile value | |
@ -665,13 +584,7 @@ Vacuum the database
| ---- | ----------- | ------ |
| 200 | Database vacuumed | boolean |
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find user \| Failed to vacuum database | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
| 500 | Failed to find user \| Failed to ExecVacuum database | |
---
### /api/v1/resource
@ -696,12 +609,6 @@ Get a list of resources
| 401 | Missing user in session | |
| 500 | Failed to fetch resource list | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### POST
##### Summary
@ -722,12 +629,6 @@ Create resource
| 401 | Missing user in session | |
| 500 | Failed to save resource \| Failed to create resource \| Failed to create activity | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/resource/{resourceId}
#### DELETE
@ -751,12 +652,6 @@ Delete a resource
| 404 | Resource not found: %d | |
| 500 | Failed to find resource \| Failed to delete resource | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### PATCH
##### Summary
@ -779,12 +674,6 @@ Update a resource
| 404 | Resource not found: %d | |
| 500 | Failed to find resource \| Failed to patch resource | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/resource/blob
#### POST
@ -807,12 +696,6 @@ Upload resource
| 401 | Missing user in session | |
| 500 | Failed to get uploading file \| Failed to open file \| Failed to save resource \| Failed to create resource \| Failed to create activity | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /o/r/{resourceId}
#### GET
@ -857,12 +740,6 @@ Get a list of storages
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find user \| Failed to convert storage | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### POST
##### Summary
@ -883,12 +760,6 @@ Create storage
| 401 | Missing user in session | |
| 500 | Failed to find user \| Failed to create storage \| Failed to convert storage | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/storage/{storageId}
#### DELETE
@ -911,12 +782,6 @@ Delete a storage
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find user \| Failed to find storage \| Failed to unmarshal storage service id \| Failed to delete storage | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### PATCH
##### Summary
@ -938,12 +803,6 @@ Update a storage
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find user \| Failed to patch storage \| Failed to convert storage | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
---
### /api/v1/system/setting
@ -960,12 +819,6 @@ Get a list of system settings
| 401 | Missing user in session \| Unauthorized | |
| 500 | Failed to find user \| Failed to find system setting list | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### POST
##### Summary
@ -987,12 +840,6 @@ Create system setting
| 403 | Cannot disable passwords if no SSO identity provider is configured. | |
| 500 | Failed to find user \| Failed to upsert system setting | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
---
### /api/v1/tag
@ -1009,12 +856,6 @@ Get a list of tags
| 400 | Missing user id to find tag | |
| 500 | Failed to find tag list | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
#### POST
##### Summary
@ -1035,12 +876,6 @@ Create a tag
| 401 | Missing user in session | |
| 500 | Failed to upsert tag \| Failed to create activity | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/tag/delete
#### POST
@ -1063,12 +898,6 @@ Delete a tag
| 401 | Missing user in session | |
| 500 | Failed to delete tag name: %v | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/tag/suggestion
#### GET
@ -1084,12 +913,6 @@ Get a list of tags suggested from other memos contents
| 400 | Missing user session | |
| 500 | Failed to find memo list \| Failed to find tag list | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
---
### /api/v1/user
@ -1206,12 +1029,6 @@ Get current user
| 401 | Missing auth session | |
| 500 | Failed to find user \| Failed to find userSettingList | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
### /api/v1/user/name/{username}
#### GET
@ -1239,7 +1056,7 @@ Get user by username
#### POST
##### Summary
Create user setting
Upsert user setting
##### Parameters
@ -1251,17 +1068,11 @@ Create user setting
| Code | Description | Schema |
| ---- | ----------- | ------ |
| 200 | Created user setting | [store.UserSetting](#storeusersetting) |
| 200 | Created user setting | [github_com_usememos_memos_store.UserSetting](#github_com_usememos_memos_storeusersetting) |
| 400 | Malformatted post user setting upsert request \| Invalid user setting format | |
| 401 | Missing auth session | |
| 500 | Failed to upsert user setting | |
##### Security
| Security Schema | Scopes |
| --------------- | ------ |
| ApiKeyAuth | |
---
### /explore/rss.xml
@ -1299,7 +1110,28 @@ Get RSS for a user
| 500 | Failed to get system customized profile \| Failed to find memo list \| Failed to generate rss |
---
### /o/get/httpmeta
### /o/get/GetImage
#### GET
##### Summary
Get GetImage from URL
##### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| url | query | Image url | Yes | string |
##### Responses
| Code | Description |
| ---- | ----------- |
| 200 | Image |
| 400 | Missing GetImage url \| Wrong url \| Failed to get GetImage url: %s |
| 500 | Failed to write GetImage blob |
### /o/get/GetWebsiteMetadata
#### GET
##### Summary
@ -1320,27 +1152,6 @@ Get website metadata
| 400 | Missing website url \| Wrong url | |
| 406 | Failed to get website meta with url: %s | |
### /o/get/image
#### GET
##### Summary
Get image from URL
##### Parameters
| Name | Located in | Description | Required | Schema |
| ---- | ---------- | ----------- | -------- | ------ |
| url | query | Image url | Yes | string |
##### Responses
| Code | Description |
| ---- | ----------- |
| 200 | Image |
| 400 | Missing image url \| Wrong url \| Failed to get image url: %s |
| 500 | Failed to write image blob |
---
### Models
@ -1352,6 +1163,14 @@ Get image from URL
| image | string | | No |
| title | string | | No |
#### github_com_usememos_memos_store.UserSetting
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| key | string | | No |
| userID | integer | | No |
| value | string | | No |
#### profile.Profile
| Name | Type | Description | Required |
@ -1484,21 +1303,12 @@ Get image from URL
| email | string | | No |
| id | integer | | No |
| nickname | string | | No |
| openID | string | | No |
| passwordHash | string | | No |
| role | [store.Role](#storerole) | | No |
| rowStatus | [store.RowStatus](#storerowstatus) | Standard fields | No |
| updatedTs | integer | | No |
| username | string | Domain specific fields | No |
#### store.UserSetting
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| key | string | | No |
| userID | integer | | No |
| value | string | | No |
#### store.Visibility
| Name | Type | Description | Required |
@ -1528,7 +1338,6 @@ Get image from URL
| Name | Type | Description | Required |
| ---- | ---- | ----------- | -------- |
| downloadToLocal | boolean | | No |
| externalLink | string | | No |
| filename | string | | No |
| internalPath | string | | No |
@ -1766,7 +1575,6 @@ Get image from URL
| email | string | | No |
| nickname | string | | No |
| password | string | | No |
| resetOpenId | boolean | | No |
| rowStatus | [v1.RowStatus](#v1rowstatus) | | No |
| username | string | | No |
@ -1820,7 +1628,6 @@ Get image from URL
| email | string | | No |
| id | integer | | No |
| nickname | string | | No |
| openId | string | | No |
| role | [v1.Role](#v1role) | | No |
| rowStatus | [v1.RowStatus](#v1rowstatus) | Standard fields | No |
| updatedTs | integer | | No |

View File

@ -59,17 +59,15 @@ message User {
string nickname = 5;
string open_id = 6;
string avatar_url = 6;
string avatar_url = 7;
string password = 7 [(google.api.field_behavior) = INPUT_ONLY];
string password = 8 [(google.api.field_behavior) = INPUT_ONLY];
RowStatus row_status = 8;
RowStatus row_status = 9;
google.protobuf.Timestamp create_time = 9;
google.protobuf.Timestamp create_time = 10;
google.protobuf.Timestamp update_time = 11;
google.protobuf.Timestamp update_time = 10;
}
message GetUserRequest {

View File

@ -554,7 +554,6 @@
| role | [User.Role](#memos-api-v2-User-Role) | | |
| email | [string](#string) | | |
| nickname | [string](#string) | | |
| open_id | [string](#string) | | |
| avatar_url | [string](#string) | | |
| password | [string](#string) | | |
| row_status | [RowStatus](#memos-api-v2-RowStatus) | | |

View File

@ -84,12 +84,11 @@ type User struct {
Role User_Role `protobuf:"varint,3,opt,name=role,proto3,enum=memos.api.v2.User_Role" json:"role,omitempty"`
Email string `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"`
Nickname string `protobuf:"bytes,5,opt,name=nickname,proto3" json:"nickname,omitempty"`
OpenId string `protobuf:"bytes,6,opt,name=open_id,json=openId,proto3" json:"open_id,omitempty"`
AvatarUrl string `protobuf:"bytes,7,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"`
Password string `protobuf:"bytes,8,opt,name=password,proto3" json:"password,omitempty"`
RowStatus RowStatus `protobuf:"varint,9,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"`
CreateTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"`
UpdateTime *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"`
AvatarUrl string `protobuf:"bytes,6,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"`
Password string `protobuf:"bytes,7,opt,name=password,proto3" json:"password,omitempty"`
RowStatus RowStatus `protobuf:"varint,8,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"`
CreateTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"`
UpdateTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"`
}
func (x *User) Reset() {
@ -159,13 +158,6 @@ func (x *User) GetNickname() string {
return ""
}
func (x *User) GetOpenId() string {
if x != nil {
return x.OpenId
}
return ""
}
func (x *User) GetAvatarUrl() string {
if x != nil {
return x.AvatarUrl
@ -781,7 +773,7 @@ var file_api_v2_user_service_proto_rawDesc = []byte{
0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72,
0x2e, 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, 0xd9, 0x03, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72,
0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc0, 0x03, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64,
0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x04,
@ -790,154 +782,153 @@ var file_api_v2_user_service_proto_rawDesc = []byte{
0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61,
0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12,
0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6f,
0x70, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x70,
0x65, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75,
0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72,
0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18,
0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x04, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73,
0x77, 0x6f, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74,
0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73,
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, 0x3b, 0x0a, 0x0b,
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 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, 0x0a, 0x63,
0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64,
0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 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, 0x0a, 0x75, 0x70, 0x64, 0x61,
0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x3b, 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, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x09,
0x0a, 0x05, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45,
0x52, 0x10, 0x03, 0x22, 0x2c, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
0x65, 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,
0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61,
0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61,
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41,
0x04, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0a, 0x72,
0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69,
0x6d, 0x65, 0x18, 0x09, 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, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65,
0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
0x0a, 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, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x3b, 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, 0x08, 0x0a, 0x04, 0x48,
0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x02,
0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x03, 0x22, 0x2c, 0x0a, 0x0e, 0x47, 0x65,
0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08,
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 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, 0x6d, 0x65, 0x6d, 0x6f,
0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75,
0x73, 0x65, 0x72, 0x22, 0x78, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65,
0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x78, 0x0a, 0x11,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a,
0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65,
0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52,
0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f,
0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61,
0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x3c, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
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, 0x6d, 0x65, 0x6d,
0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04,
0x75, 0x73, 0x65, 0x72, 0x22, 0x39, 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, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x85, 0x01, 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, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
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, 0x6d, 0x65,
0x6d, 0x6f, 0x73, 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,
0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x03, 0x28,
0x09, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x3c, 0x0a,
0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x39, 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, 0x1a, 0x0a, 0x08, 0x75, 0x73,
0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73,
0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 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,
0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x85, 0x01, 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, 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,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x5d,
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, 0x1a,
0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 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, 0x32, 0xb9, 0x06, 0x0a, 0x0b,
0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x07, 0x47,
0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x2b, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f,
0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d,
0x12, 0x7f, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1f,
0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x2e, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x22, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
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, 0x6d, 0x65, 0x6d, 0x6f,
0x73, 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, 0x5d, 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, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d,
0x65, 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, 0x32, 0xb9, 0x06, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x12, 0x73, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e,
0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x6d, 0x65,
0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73,
0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0xda, 0x41, 0x08, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73,
0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x7f, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65,
0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x22, 0x18,
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75,
0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xa8, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x6d,
0x65, 0x6d, 0x6f, 0x73, 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, 0x39, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65,
0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x73, 0x12, 0xbe, 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,
0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x6d, 0x65, 0x6d, 0x6f,
0x73, 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, 0x4c, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e,
0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x3a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f,
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x26, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65,
0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f,
0x6b, 0x65, 0x6e, 0x73, 0x12, 0xc7, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x6d, 0x65, 0x6d,
0x6f, 0x73, 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, 0x55, 0xda, 0x41, 0x15, 0x75, 0x73, 0x65, 0x72,
0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x2a, 0x35, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
0x7d, 0x12, 0xa8, 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, 0x6d, 0x65, 0x6d,
0x6f, 0x73, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x39, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73,
0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x61,
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xbe, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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,
0x4c, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x3b, 0x3a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x26, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75,
0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f,
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xc7, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x55, 0xda, 0x41, 0x15, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x61, 0x63,
0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37,
0x2a, 0x35, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f,
0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 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, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e,
0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65,
0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c,
0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41,
0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a,
0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
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, 0xa8,
0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 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, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d,
0x6f, 0x73, 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, 0x4d, 0x41, 0x58, 0xaa,
0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02,
0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18,
0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73,
0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (

View File

@ -23,7 +23,6 @@ CREATE TABLE user (
email TEXT NOT NULL DEFAULT '',
nickname TEXT NOT NULL DEFAULT '',
password_hash TEXT NOT NULL,
open_id TEXT NOT NULL UNIQUE,
avatar_url TEXT NOT NULL DEFAULT ''
);

View File

@ -0,0 +1,25 @@
DROP TABLE IF EXISTS user_temp;
CREATE TABLE user_temp (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
row_status TEXT NOT NULL CHECK (row_status IN ('NORMAL', 'ARCHIVED')) DEFAULT 'NORMAL',
username TEXT NOT NULL UNIQUE,
role TEXT NOT NULL CHECK (role IN ('HOST', 'ADMIN', 'USER')) DEFAULT 'USER',
email TEXT NOT NULL DEFAULT '',
nickname TEXT NOT NULL DEFAULT '',
password_hash TEXT NOT NULL,
avatar_url TEXT NOT NULL DEFAULT ''
);
INSERT INTO
user_temp (id, created_ts, updated_ts, row_status, username, role, email, nickname, password_hash, avatar_url)
SELECT
id, created_ts, updated_ts, row_status, username, role, email, nickname, password_hash, avatar_url
FROM
user;
DROP TABLE user;
ALTER TABLE user_temp_temp RENAME TO user_temp;

View File

@ -23,7 +23,6 @@ CREATE TABLE user (
email TEXT NOT NULL DEFAULT '',
nickname TEXT NOT NULL DEFAULT '',
password_hash TEXT NOT NULL,
open_id TEXT NOT NULL UNIQUE,
avatar_url TEXT NOT NULL DEFAULT ''
);

View File

@ -43,7 +43,6 @@ type User struct {
Email string
Nickname string
PasswordHash string
OpenID string
AvatarURL string
}
@ -59,7 +58,6 @@ type UpdateUser struct {
Password *string
AvatarURL *string
PasswordHash *string
OpenID *string
}
type FindUser struct {
@ -69,7 +67,6 @@ type FindUser struct {
Role *Role
Email *string
Nickname *string
OpenID *string
}
type DeleteUser struct {
@ -83,10 +80,9 @@ func (s *Store) CreateUser(ctx context.Context, create *User) (*User, error) {
role,
email,
nickname,
password_hash,
open_id
password_hash
)
VALUES (?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?)
RETURNING id, avatar_url, created_ts, updated_ts, row_status
`
if err := s.db.QueryRowContext(
@ -97,7 +93,6 @@ func (s *Store) CreateUser(ctx context.Context, create *User) (*User, error) {
create.Email,
create.Nickname,
create.PasswordHash,
create.OpenID,
).Scan(
&create.ID,
&create.AvatarURL,
@ -136,16 +131,13 @@ func (s *Store) UpdateUser(ctx context.Context, update *UpdateUser) (*User, erro
if v := update.PasswordHash; v != nil {
set, args = append(set, "password_hash = ?"), append(args, *v)
}
if v := update.OpenID; v != nil {
set, args = append(set, "open_id = ?"), append(args, *v)
}
args = append(args, update.ID)
query := `
UPDATE user
SET ` + strings.Join(set, ", ") + `
WHERE id = ?
RETURNING id, username, role, email, nickname, password_hash, open_id, avatar_url, created_ts, updated_ts, row_status
RETURNING id, username, role, email, nickname, password_hash, avatar_url, created_ts, updated_ts, row_status
`
user := &User{}
if err := s.db.QueryRowContext(ctx, query, args...).Scan(
@ -155,7 +147,6 @@ func (s *Store) UpdateUser(ctx context.Context, update *UpdateUser) (*User, erro
&user.Email,
&user.Nickname,
&user.PasswordHash,
&user.OpenID,
&user.AvatarURL,
&user.CreatedTs,
&user.UpdatedTs,
@ -186,9 +177,6 @@ func (s *Store) ListUsers(ctx context.Context, find *FindUser) ([]*User, error)
if v := find.Nickname; v != nil {
where, args = append(where, "nickname = ?"), append(args, *v)
}
if v := find.OpenID; v != nil {
where, args = append(where, "open_id = ?"), append(args, *v)
}
query := `
SELECT
@ -198,7 +186,6 @@ func (s *Store) ListUsers(ctx context.Context, find *FindUser) ([]*User, error)
email,
nickname,
password_hash,
open_id,
avatar_url,
created_ts,
updated_ts,
@ -223,7 +210,6 @@ func (s *Store) ListUsers(ctx context.Context, find *FindUser) ([]*User, error)
&user.Email,
&user.Nickname,
&user.PasswordHash,
&user.OpenID,
&user.AvatarURL,
&user.CreatedTs,
&user.UpdatedTs,

View File

@ -42,7 +42,6 @@ func createTestingHostUser(ctx context.Context, ts *store.Store) (*store.User, e
Role: store.RoleHost,
Email: "test@test.com",
Nickname: "test_nickname",
OpenID: "test_open_id",
}
passwordHash, err := bcrypt.GenerateFromPassword([]byte("test_password"), bcrypt.DefaultCost)
if err != nil {

View File

@ -1,37 +1,13 @@
import { Button, Input, Textarea } from "@mui/joy";
import { Button } from "@mui/joy";
import useCurrentUser from "@/hooks/useCurrentUser";
import { useUserV1Store } from "@/store/v1";
import { useTranslate } from "@/utils/i18n";
import showChangePasswordDialog from "../ChangePasswordDialog";
import { showCommonDialog } from "../Dialog/CommonDialog";
import Icon from "../Icon";
import showUpdateAccountDialog from "../UpdateAccountDialog";
import UserAvatar from "../UserAvatar";
const MyAccountSection = () => {
const t = useTranslate();
const userV1Store = useUserV1Store();
const user = useCurrentUser();
const openAPIRoute = `${window.location.origin}/api/v1/memo?openId=${user.openId}`;
const handleResetOpenIdBtnClick = async () => {
showCommonDialog({
title: t("setting.account-section.openapi-reset"),
content: t("setting.account-section.openapi-reset-warning"),
style: "warning",
dialogName: "reset-openid-dialog",
onConfirm: async () => {
await userV1Store.updateUser(
{
username: user.username,
},
["reset_open_id"]
);
},
});
};
const exampleWithCurl = `curl '${openAPIRoute}' -H 'Content-Type: application/json' --data-raw '{"content":"Hello world!"}'`;
return (
<>
@ -52,17 +28,6 @@ const MyAccountSection = () => {
</Button>
</div>
</div>
<div className="section-container openapi-section-container mt-6">
<p className="title-text">Open ID</p>
<div className="w-full flex flex-row justify-start items-center">
<Input className="grow mr-2" value={user.openId} readOnly />
<Button className="shrink-0" color="neutral" variant="outlined" onClick={handleResetOpenIdBtnClick}>
<Icon.RefreshCw className="h-4 w-4" />
</Button>
</div>
<p className="title-text">Open API Example with cURL</p>
<Textarea className="w-full !font-mono !text-sm whitespace-pre" value={exampleWithCurl} readOnly />
</div>
</>
);
};

View File

@ -12,7 +12,6 @@ interface User {
role: UserRole;
email: string;
nickname: string;
openId: string;
avatarUrl: string;
userSettingList: UserSetting[];
@ -34,7 +33,6 @@ interface UserPatch {
nickname?: string;
avatarUrl?: string;
password?: string;
resetOpenId?: boolean;
}
interface UserDelete {

View File

@ -37,32 +37,27 @@ export declare class User extends Message<User> {
nickname: string;
/**
* @generated from field: string open_id = 6;
*/
openId: string;
/**
* @generated from field: string avatar_url = 7;
* @generated from field: string avatar_url = 6;
*/
avatarUrl: string;
/**
* @generated from field: string password = 8;
* @generated from field: string password = 7;
*/
password: string;
/**
* @generated from field: memos.api.v2.RowStatus row_status = 9;
* @generated from field: memos.api.v2.RowStatus row_status = 8;
*/
rowStatus: RowStatus;
/**
* @generated from field: google.protobuf.Timestamp create_time = 10;
* @generated from field: google.protobuf.Timestamp create_time = 9;
*/
createTime?: Timestamp;
/**
* @generated from field: google.protobuf.Timestamp update_time = 11;
* @generated from field: google.protobuf.Timestamp update_time = 10;
*/
updateTime?: Timestamp;

View File

@ -17,12 +17,11 @@ export const User = proto3.makeMessageType(
{ no: 3, name: "role", kind: "enum", T: proto3.getEnumType(User_Role) },
{ no: 4, name: "email", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 5, name: "nickname", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 6, name: "open_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 7, name: "avatar_url", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 8, name: "password", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 9, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) },
{ no: 10, name: "create_time", kind: "message", T: Timestamp },
{ no: 11, name: "update_time", kind: "message", T: Timestamp },
{ no: 6, name: "avatar_url", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 7, name: "password", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 8, name: "row_status", kind: "enum", T: proto3.getEnumType(RowStatus) },
{ no: 9, name: "create_time", kind: "message", T: Timestamp },
{ no: 10, name: "update_time", kind: "message", T: Timestamp },
],
);