refactor: expose shared memo as memo resource

Rename GetMemoByShare to GetSharedMemo and move REST resolution to /api/v1/shares/{share_token}/memo.\n\nBREAKING CHANGE: remove GET /api/v1/shares/{share_id} and the GetMemoByShare RPC.
This commit is contained in:
johnnyjoygh 2026-07-26 21:13:18 +08:00
parent 390126f1cd
commit 0d2cbd4f5a
16 changed files with 146 additions and 145 deletions

View file

@ -128,10 +128,10 @@ service MemoService {
option (google.api.http) = {delete: "/api/v1/{name=memos/*/shares/*}"}; option (google.api.http) = {delete: "/api/v1/{name=memos/*/shares/*}"};
option (google.api.method_signature) = "name"; option (google.api.method_signature) = "name";
} }
// GetMemoByShare resolves a share token to its memo. No authentication required. // GetSharedMemo resolves a share token to its memo. No authentication required.
// Returns NOT_FOUND if the token is invalid or expired. // Returns NOT_FOUND if the token is invalid or expired.
rpc GetMemoByShare(GetMemoByShareRequest) returns (Memo) { rpc GetSharedMemo(GetSharedMemoRequest) returns (Memo) {
option (google.api.http) = {get: "/api/v1/shares/{share_id}"}; option (google.api.http) = {get: "/api/v1/shares/{share_token}/memo"};
} }
// GetLinkMetadata gets metadata for a link. // GetLinkMetadata gets metadata for a link.
rpc GetLinkMetadata(GetLinkMetadataRequest) returns (LinkMetadata) { rpc GetLinkMetadata(GetLinkMetadataRequest) returns (LinkMetadata) {
@ -622,9 +622,9 @@ message DeleteMemoShareRequest {
]; ];
} }
message GetMemoByShareRequest { message GetSharedMemoRequest {
// Required. The share token extracted from the share URL (/s/{share_id}). // Required. The opaque bearer token extracted from the share URL.
string share_id = 1 [(google.api.field_behavior) = REQUIRED]; string share_token = 1 [(google.api.field_behavior) = REQUIRED];
} }
message GetLinkMetadataRequest { message GetLinkMetadataRequest {

View file

@ -23,7 +23,7 @@ plugins:
- remote: buf.build/community/google-gnostic-openapi - remote: buf.build/community/google-gnostic-openapi
out: gen out: gen
opt: enum_type=string opt: enum_type=string
- remote: buf.build/bufbuild/es - remote: buf.build/bufbuild/es:v2.12.1
out: ../web/src/types/proto out: ../web/src/types/proto
opt: opt:
- target=ts - target=ts

View file

@ -80,9 +80,9 @@ const (
// MemoServiceDeleteMemoShareProcedure is the fully-qualified name of the MemoService's // MemoServiceDeleteMemoShareProcedure is the fully-qualified name of the MemoService's
// DeleteMemoShare RPC. // DeleteMemoShare RPC.
MemoServiceDeleteMemoShareProcedure = "/memos.api.v1.MemoService/DeleteMemoShare" MemoServiceDeleteMemoShareProcedure = "/memos.api.v1.MemoService/DeleteMemoShare"
// MemoServiceGetMemoByShareProcedure is the fully-qualified name of the MemoService's // MemoServiceGetSharedMemoProcedure is the fully-qualified name of the MemoService's GetSharedMemo
// GetMemoByShare RPC. // RPC.
MemoServiceGetMemoByShareProcedure = "/memos.api.v1.MemoService/GetMemoByShare" MemoServiceGetSharedMemoProcedure = "/memos.api.v1.MemoService/GetSharedMemo"
// MemoServiceGetLinkMetadataProcedure is the fully-qualified name of the MemoService's // MemoServiceGetLinkMetadataProcedure is the fully-qualified name of the MemoService's
// GetLinkMetadata RPC. // GetLinkMetadata RPC.
MemoServiceGetLinkMetadataProcedure = "/memos.api.v1.MemoService/GetLinkMetadata" MemoServiceGetLinkMetadataProcedure = "/memos.api.v1.MemoService/GetLinkMetadata"
@ -134,9 +134,9 @@ type MemoServiceClient interface {
ListMemoShares(context.Context, *connect.Request[v1.ListMemoSharesRequest]) (*connect.Response[v1.ListMemoSharesResponse], error) ListMemoShares(context.Context, *connect.Request[v1.ListMemoSharesRequest]) (*connect.Response[v1.ListMemoSharesResponse], error)
// DeleteMemoShare revokes a share link. Requires authentication as the memo creator. // DeleteMemoShare revokes a share link. Requires authentication as the memo creator.
DeleteMemoShare(context.Context, *connect.Request[v1.DeleteMemoShareRequest]) (*connect.Response[emptypb.Empty], error) DeleteMemoShare(context.Context, *connect.Request[v1.DeleteMemoShareRequest]) (*connect.Response[emptypb.Empty], error)
// GetMemoByShare resolves a share token to its memo. No authentication required. // GetSharedMemo resolves a share token to its memo. No authentication required.
// Returns NOT_FOUND if the token is invalid or expired. // Returns NOT_FOUND if the token is invalid or expired.
GetMemoByShare(context.Context, *connect.Request[v1.GetMemoByShareRequest]) (*connect.Response[v1.Memo], error) GetSharedMemo(context.Context, *connect.Request[v1.GetSharedMemoRequest]) (*connect.Response[v1.Memo], error)
// GetLinkMetadata gets metadata for a link. // GetLinkMetadata gets metadata for a link.
GetLinkMetadata(context.Context, *connect.Request[v1.GetLinkMetadataRequest]) (*connect.Response[v1.LinkMetadata], error) GetLinkMetadata(context.Context, *connect.Request[v1.GetLinkMetadataRequest]) (*connect.Response[v1.LinkMetadata], error)
// BatchGetLinkMetadata gets metadata for links. // BatchGetLinkMetadata gets metadata for links.
@ -256,10 +256,10 @@ func NewMemoServiceClient(httpClient connect.HTTPClient, baseURL string, opts ..
connect.WithSchema(memoServiceMethods.ByName("DeleteMemoShare")), connect.WithSchema(memoServiceMethods.ByName("DeleteMemoShare")),
connect.WithClientOptions(opts...), connect.WithClientOptions(opts...),
), ),
getMemoByShare: connect.NewClient[v1.GetMemoByShareRequest, v1.Memo]( getSharedMemo: connect.NewClient[v1.GetSharedMemoRequest, v1.Memo](
httpClient, httpClient,
baseURL+MemoServiceGetMemoByShareProcedure, baseURL+MemoServiceGetSharedMemoProcedure,
connect.WithSchema(memoServiceMethods.ByName("GetMemoByShare")), connect.WithSchema(memoServiceMethods.ByName("GetSharedMemo")),
connect.WithClientOptions(opts...), connect.WithClientOptions(opts...),
), ),
getLinkMetadata: connect.NewClient[v1.GetLinkMetadataRequest, v1.LinkMetadata]( getLinkMetadata: connect.NewClient[v1.GetLinkMetadataRequest, v1.LinkMetadata](
@ -296,7 +296,7 @@ type memoServiceClient struct {
createMemoShare *connect.Client[v1.CreateMemoShareRequest, v1.MemoShare] createMemoShare *connect.Client[v1.CreateMemoShareRequest, v1.MemoShare]
listMemoShares *connect.Client[v1.ListMemoSharesRequest, v1.ListMemoSharesResponse] listMemoShares *connect.Client[v1.ListMemoSharesRequest, v1.ListMemoSharesResponse]
deleteMemoShare *connect.Client[v1.DeleteMemoShareRequest, emptypb.Empty] deleteMemoShare *connect.Client[v1.DeleteMemoShareRequest, emptypb.Empty]
getMemoByShare *connect.Client[v1.GetMemoByShareRequest, v1.Memo] getSharedMemo *connect.Client[v1.GetSharedMemoRequest, v1.Memo]
getLinkMetadata *connect.Client[v1.GetLinkMetadataRequest, v1.LinkMetadata] getLinkMetadata *connect.Client[v1.GetLinkMetadataRequest, v1.LinkMetadata]
batchGetLinkMetadata *connect.Client[v1.BatchGetLinkMetadataRequest, v1.BatchGetLinkMetadataResponse] batchGetLinkMetadata *connect.Client[v1.BatchGetLinkMetadataRequest, v1.BatchGetLinkMetadataResponse]
} }
@ -386,9 +386,9 @@ func (c *memoServiceClient) DeleteMemoShare(ctx context.Context, req *connect.Re
return c.deleteMemoShare.CallUnary(ctx, req) return c.deleteMemoShare.CallUnary(ctx, req)
} }
// GetMemoByShare calls memos.api.v1.MemoService.GetMemoByShare. // GetSharedMemo calls memos.api.v1.MemoService.GetSharedMemo.
func (c *memoServiceClient) GetMemoByShare(ctx context.Context, req *connect.Request[v1.GetMemoByShareRequest]) (*connect.Response[v1.Memo], error) { func (c *memoServiceClient) GetSharedMemo(ctx context.Context, req *connect.Request[v1.GetSharedMemoRequest]) (*connect.Response[v1.Memo], error) {
return c.getMemoByShare.CallUnary(ctx, req) return c.getSharedMemo.CallUnary(ctx, req)
} }
// GetLinkMetadata calls memos.api.v1.MemoService.GetLinkMetadata. // GetLinkMetadata calls memos.api.v1.MemoService.GetLinkMetadata.
@ -444,9 +444,9 @@ type MemoServiceHandler interface {
ListMemoShares(context.Context, *connect.Request[v1.ListMemoSharesRequest]) (*connect.Response[v1.ListMemoSharesResponse], error) ListMemoShares(context.Context, *connect.Request[v1.ListMemoSharesRequest]) (*connect.Response[v1.ListMemoSharesResponse], error)
// DeleteMemoShare revokes a share link. Requires authentication as the memo creator. // DeleteMemoShare revokes a share link. Requires authentication as the memo creator.
DeleteMemoShare(context.Context, *connect.Request[v1.DeleteMemoShareRequest]) (*connect.Response[emptypb.Empty], error) DeleteMemoShare(context.Context, *connect.Request[v1.DeleteMemoShareRequest]) (*connect.Response[emptypb.Empty], error)
// GetMemoByShare resolves a share token to its memo. No authentication required. // GetSharedMemo resolves a share token to its memo. No authentication required.
// Returns NOT_FOUND if the token is invalid or expired. // Returns NOT_FOUND if the token is invalid or expired.
GetMemoByShare(context.Context, *connect.Request[v1.GetMemoByShareRequest]) (*connect.Response[v1.Memo], error) GetSharedMemo(context.Context, *connect.Request[v1.GetSharedMemoRequest]) (*connect.Response[v1.Memo], error)
// GetLinkMetadata gets metadata for a link. // GetLinkMetadata gets metadata for a link.
GetLinkMetadata(context.Context, *connect.Request[v1.GetLinkMetadataRequest]) (*connect.Response[v1.LinkMetadata], error) GetLinkMetadata(context.Context, *connect.Request[v1.GetLinkMetadataRequest]) (*connect.Response[v1.LinkMetadata], error)
// BatchGetLinkMetadata gets metadata for links. // BatchGetLinkMetadata gets metadata for links.
@ -562,10 +562,10 @@ func NewMemoServiceHandler(svc MemoServiceHandler, opts ...connect.HandlerOption
connect.WithSchema(memoServiceMethods.ByName("DeleteMemoShare")), connect.WithSchema(memoServiceMethods.ByName("DeleteMemoShare")),
connect.WithHandlerOptions(opts...), connect.WithHandlerOptions(opts...),
) )
memoServiceGetMemoByShareHandler := connect.NewUnaryHandler( memoServiceGetSharedMemoHandler := connect.NewUnaryHandler(
MemoServiceGetMemoByShareProcedure, MemoServiceGetSharedMemoProcedure,
svc.GetMemoByShare, svc.GetSharedMemo,
connect.WithSchema(memoServiceMethods.ByName("GetMemoByShare")), connect.WithSchema(memoServiceMethods.ByName("GetSharedMemo")),
connect.WithHandlerOptions(opts...), connect.WithHandlerOptions(opts...),
) )
memoServiceGetLinkMetadataHandler := connect.NewUnaryHandler( memoServiceGetLinkMetadataHandler := connect.NewUnaryHandler(
@ -616,8 +616,8 @@ func NewMemoServiceHandler(svc MemoServiceHandler, opts ...connect.HandlerOption
memoServiceListMemoSharesHandler.ServeHTTP(w, r) memoServiceListMemoSharesHandler.ServeHTTP(w, r)
case MemoServiceDeleteMemoShareProcedure: case MemoServiceDeleteMemoShareProcedure:
memoServiceDeleteMemoShareHandler.ServeHTTP(w, r) memoServiceDeleteMemoShareHandler.ServeHTTP(w, r)
case MemoServiceGetMemoByShareProcedure: case MemoServiceGetSharedMemoProcedure:
memoServiceGetMemoByShareHandler.ServeHTTP(w, r) memoServiceGetSharedMemoHandler.ServeHTTP(w, r)
case MemoServiceGetLinkMetadataProcedure: case MemoServiceGetLinkMetadataProcedure:
memoServiceGetLinkMetadataHandler.ServeHTTP(w, r) memoServiceGetLinkMetadataHandler.ServeHTTP(w, r)
case MemoServiceBatchGetLinkMetadataProcedure: case MemoServiceBatchGetLinkMetadataProcedure:
@ -699,8 +699,8 @@ func (UnimplementedMemoServiceHandler) DeleteMemoShare(context.Context, *connect
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.DeleteMemoShare is not implemented")) return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.DeleteMemoShare is not implemented"))
} }
func (UnimplementedMemoServiceHandler) GetMemoByShare(context.Context, *connect.Request[v1.GetMemoByShareRequest]) (*connect.Response[v1.Memo], error) { func (UnimplementedMemoServiceHandler) GetSharedMemo(context.Context, *connect.Request[v1.GetSharedMemoRequest]) (*connect.Response[v1.Memo], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.GetMemoByShare is not implemented")) return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.GetSharedMemo is not implemented"))
} }
func (UnimplementedMemoServiceHandler) GetLinkMetadata(context.Context, *connect.Request[v1.GetLinkMetadataRequest]) (*connect.Response[v1.LinkMetadata], error) { func (UnimplementedMemoServiceHandler) GetLinkMetadata(context.Context, *connect.Request[v1.GetLinkMetadataRequest]) (*connect.Response[v1.LinkMetadata], error) {

View file

@ -1925,28 +1925,28 @@ func (x *DeleteMemoShareRequest) GetName() string {
return "" return ""
} }
type GetMemoByShareRequest struct { type GetSharedMemoRequest struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
// Required. The share token extracted from the share URL (/s/{share_id}). // Required. The opaque bearer token extracted from the share URL.
ShareId string `protobuf:"bytes,1,opt,name=share_id,json=shareId,proto3" json:"share_id,omitempty"` ShareToken string `protobuf:"bytes,1,opt,name=share_token,json=shareToken,proto3" json:"share_token,omitempty"`
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
func (x *GetMemoByShareRequest) Reset() { func (x *GetSharedMemoRequest) Reset() {
*x = GetMemoByShareRequest{} *x = GetSharedMemoRequest{}
mi := &file_api_v1_memo_service_proto_msgTypes[28] mi := &file_api_v1_memo_service_proto_msgTypes[28]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
func (x *GetMemoByShareRequest) String() string { func (x *GetSharedMemoRequest) String() string {
return protoimpl.X.MessageStringOf(x) return protoimpl.X.MessageStringOf(x)
} }
func (*GetMemoByShareRequest) ProtoMessage() {} func (*GetSharedMemoRequest) ProtoMessage() {}
func (x *GetMemoByShareRequest) ProtoReflect() protoreflect.Message { func (x *GetSharedMemoRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v1_memo_service_proto_msgTypes[28] mi := &file_api_v1_memo_service_proto_msgTypes[28]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -1958,14 +1958,14 @@ func (x *GetMemoByShareRequest) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x) return mi.MessageOf(x)
} }
// Deprecated: Use GetMemoByShareRequest.ProtoReflect.Descriptor instead. // Deprecated: Use GetSharedMemoRequest.ProtoReflect.Descriptor instead.
func (*GetMemoByShareRequest) Descriptor() ([]byte, []int) { func (*GetSharedMemoRequest) Descriptor() ([]byte, []int) {
return file_api_v1_memo_service_proto_rawDescGZIP(), []int{28} return file_api_v1_memo_service_proto_rawDescGZIP(), []int{28}
} }
func (x *GetMemoByShareRequest) GetShareId() string { func (x *GetSharedMemoRequest) GetShareToken() string {
if x != nil { if x != nil {
return x.ShareId return x.ShareToken
} }
return "" return ""
} }
@ -2480,9 +2480,10 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"memoShares\"L\n" + "memoShares\"L\n" +
"\x16DeleteMemoShareRequest\x122\n" + "\x16DeleteMemoShareRequest\x122\n" +
"\x04name\x18\x01 \x01(\tB\x1e\xe0A\x02\xfaA\x18\n" + "\x04name\x18\x01 \x01(\tB\x1e\xe0A\x02\xfaA\x18\n" +
"\x16memos.api.v1/MemoShareR\x04name\"7\n" + "\x16memos.api.v1/MemoShareR\x04name\"<\n" +
"\x15GetMemoByShareRequest\x12\x1e\n" + "\x14GetSharedMemoRequest\x12$\n" +
"\bshare_id\x18\x01 \x01(\tB\x03\xe0A\x02R\ashareId\"/\n" + "\vshare_token\x18\x01 \x01(\tB\x03\xe0A\x02R\n" +
"shareToken\"/\n" +
"\x16GetLinkMetadataRequest\x12\x15\n" + "\x16GetLinkMetadataRequest\x12\x15\n" +
"\x03url\x18\x01 \x01(\tB\x03\xe0A\x02R\x03url\"6\n" + "\x03url\x18\x01 \x01(\tB\x03\xe0A\x02R\x03url\"6\n" +
"\x1bBatchGetLinkMetadataRequest\x12\x17\n" + "\x1bBatchGetLinkMetadataRequest\x12\x17\n" +
@ -2500,7 +2501,7 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"\aPRIVATE\x10\x01\x12\r\n" + "\aPRIVATE\x10\x01\x12\r\n" +
"\tPROTECTED\x10\x02\x12\n" + "\tPROTECTED\x10\x02\x12\n" +
"\n" + "\n" +
"\x06PUBLIC\x10\x032\x8b\x15\n" + "\x06PUBLIC\x10\x032\x91\x15\n" +
"\vMemoService\x12e\n" + "\vMemoService\x12e\n" +
"\n" + "\n" +
"CreateMemo\x12\x1f.memos.api.v1.CreateMemoRequest\x1a\x12.memos.api.v1.Memo\"\"\xdaA\x04memo\x82\xd3\xe4\x93\x02\x15:\x04memo\"\r/api/v1/memos\x12f\n" + "CreateMemo\x12\x1f.memos.api.v1.CreateMemoRequest\x1a\x12.memos.api.v1.Memo\"\"\xdaA\x04memo\x82\xd3\xe4\x93\x02\x15:\x04memo\"\r/api/v1/memos\x12f\n" +
@ -2522,8 +2523,8 @@ const file_api_v1_memo_service_proto_rawDesc = "" +
"\x0fCreateMemoShare\x12$.memos.api.v1.CreateMemoShareRequest\x1a\x17.memos.api.v1.MemoShare\"G\xdaA\x11parent,memo_share\x82\xd3\xe4\x93\x02-:\n" + "\x0fCreateMemoShare\x12$.memos.api.v1.CreateMemoShareRequest\x1a\x17.memos.api.v1.MemoShare\"G\xdaA\x11parent,memo_share\x82\xd3\xe4\x93\x02-:\n" +
"memo_share\"\x1f/api/v1/{parent=memos/*}/shares\x12\x8d\x01\n" + "memo_share\"\x1f/api/v1/{parent=memos/*}/shares\x12\x8d\x01\n" +
"\x0eListMemoShares\x12#.memos.api.v1.ListMemoSharesRequest\x1a$.memos.api.v1.ListMemoSharesResponse\"0\xdaA\x06parent\x82\xd3\xe4\x93\x02!\x12\x1f/api/v1/{parent=memos/*}/shares\x12\x7f\n" + "\x0eListMemoShares\x12#.memos.api.v1.ListMemoSharesRequest\x1a$.memos.api.v1.ListMemoSharesResponse\"0\xdaA\x06parent\x82\xd3\xe4\x93\x02!\x12\x1f/api/v1/{parent=memos/*}/shares\x12\x7f\n" +
"\x0fDeleteMemoShare\x12$.memos.api.v1.DeleteMemoShareRequest\x1a\x16.google.protobuf.Empty\".\xdaA\x04name\x82\xd3\xe4\x93\x02!*\x1f/api/v1/{name=memos/*/shares/*}\x12l\n" + "\x0fDeleteMemoShare\x12$.memos.api.v1.DeleteMemoShareRequest\x1a\x16.google.protobuf.Empty\".\xdaA\x04name\x82\xd3\xe4\x93\x02!*\x1f/api/v1/{name=memos/*/shares/*}\x12r\n" +
"\x0eGetMemoByShare\x12#.memos.api.v1.GetMemoByShareRequest\x1a\x12.memos.api.v1.Memo\"!\x82\xd3\xe4\x93\x02\x1b\x12\x19/api/v1/shares/{share_id}\x12y\n" + "\rGetSharedMemo\x12\".memos.api.v1.GetSharedMemoRequest\x1a\x12.memos.api.v1.Memo\")\x82\xd3\xe4\x93\x02#\x12!/api/v1/shares/{share_token}/memo\x12y\n" +
"\x0fGetLinkMetadata\x12$.memos.api.v1.GetLinkMetadataRequest\x1a\x1a.memos.api.v1.LinkMetadata\"$\x82\xd3\xe4\x93\x02\x1e\x12\x1c/api/v1/memos/-/linkMetadata\x12\x9f\x01\n" + "\x0fGetLinkMetadata\x12$.memos.api.v1.GetLinkMetadataRequest\x1a\x1a.memos.api.v1.LinkMetadata\"$\x82\xd3\xe4\x93\x02\x1e\x12\x1c/api/v1/memos/-/linkMetadata\x12\x9f\x01\n" +
"\x14BatchGetLinkMetadata\x12).memos.api.v1.BatchGetLinkMetadataRequest\x1a*.memos.api.v1.BatchGetLinkMetadataResponse\"0\x82\xd3\xe4\x93\x02*:\x01*\"%/api/v1/memos/-/linkMetadata:batchGetB\xa8\x01\n" + "\x14BatchGetLinkMetadata\x12).memos.api.v1.BatchGetLinkMetadataRequest\x1a*.memos.api.v1.BatchGetLinkMetadataResponse\"0\x82\xd3\xe4\x93\x02*:\x01*\"%/api/v1/memos/-/linkMetadata:batchGetB\xa8\x01\n" +
"\x10com.memos.api.v1B\x10MemoServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3" "\x10com.memos.api.v1B\x10MemoServiceProtoP\x01Z0github.com/usememos/memos/proto/gen/api/v1;apiv1\xa2\x02\x03MAX\xaa\x02\fMemos.Api.V1\xca\x02\fMemos\\Api\\V1\xe2\x02\x18Memos\\Api\\V1\\GPBMetadata\xea\x02\x0eMemos::Api::V1b\x06proto3"
@ -2573,7 +2574,7 @@ var file_api_v1_memo_service_proto_goTypes = []any{
(*ListMemoSharesRequest)(nil), // 27: memos.api.v1.ListMemoSharesRequest (*ListMemoSharesRequest)(nil), // 27: memos.api.v1.ListMemoSharesRequest
(*ListMemoSharesResponse)(nil), // 28: memos.api.v1.ListMemoSharesResponse (*ListMemoSharesResponse)(nil), // 28: memos.api.v1.ListMemoSharesResponse
(*DeleteMemoShareRequest)(nil), // 29: memos.api.v1.DeleteMemoShareRequest (*DeleteMemoShareRequest)(nil), // 29: memos.api.v1.DeleteMemoShareRequest
(*GetMemoByShareRequest)(nil), // 30: memos.api.v1.GetMemoByShareRequest (*GetSharedMemoRequest)(nil), // 30: memos.api.v1.GetSharedMemoRequest
(*GetLinkMetadataRequest)(nil), // 31: memos.api.v1.GetLinkMetadataRequest (*GetLinkMetadataRequest)(nil), // 31: memos.api.v1.GetLinkMetadataRequest
(*BatchGetLinkMetadataRequest)(nil), // 32: memos.api.v1.BatchGetLinkMetadataRequest (*BatchGetLinkMetadataRequest)(nil), // 32: memos.api.v1.BatchGetLinkMetadataRequest
(*BatchGetLinkMetadataResponse)(nil), // 33: memos.api.v1.BatchGetLinkMetadataResponse (*BatchGetLinkMetadataResponse)(nil), // 33: memos.api.v1.BatchGetLinkMetadataResponse
@ -2635,7 +2636,7 @@ var file_api_v1_memo_service_proto_depIdxs = []int32{
26, // 45: memos.api.v1.MemoService.CreateMemoShare:input_type -> memos.api.v1.CreateMemoShareRequest 26, // 45: memos.api.v1.MemoService.CreateMemoShare:input_type -> memos.api.v1.CreateMemoShareRequest
27, // 46: memos.api.v1.MemoService.ListMemoShares:input_type -> memos.api.v1.ListMemoSharesRequest 27, // 46: memos.api.v1.MemoService.ListMemoShares:input_type -> memos.api.v1.ListMemoSharesRequest
29, // 47: memos.api.v1.MemoService.DeleteMemoShare:input_type -> memos.api.v1.DeleteMemoShareRequest 29, // 47: memos.api.v1.MemoService.DeleteMemoShare:input_type -> memos.api.v1.DeleteMemoShareRequest
30, // 48: memos.api.v1.MemoService.GetMemoByShare:input_type -> memos.api.v1.GetMemoByShareRequest 30, // 48: memos.api.v1.MemoService.GetSharedMemo:input_type -> memos.api.v1.GetSharedMemoRequest
31, // 49: memos.api.v1.MemoService.GetLinkMetadata:input_type -> memos.api.v1.GetLinkMetadataRequest 31, // 49: memos.api.v1.MemoService.GetLinkMetadata:input_type -> memos.api.v1.GetLinkMetadataRequest
32, // 50: memos.api.v1.MemoService.BatchGetLinkMetadata:input_type -> memos.api.v1.BatchGetLinkMetadataRequest 32, // 50: memos.api.v1.MemoService.BatchGetLinkMetadata:input_type -> memos.api.v1.BatchGetLinkMetadataRequest
3, // 51: memos.api.v1.MemoService.CreateMemo:output_type -> memos.api.v1.Memo 3, // 51: memos.api.v1.MemoService.CreateMemo:output_type -> memos.api.v1.Memo
@ -2655,7 +2656,7 @@ var file_api_v1_memo_service_proto_depIdxs = []int32{
25, // 65: memos.api.v1.MemoService.CreateMemoShare:output_type -> memos.api.v1.MemoShare 25, // 65: memos.api.v1.MemoService.CreateMemoShare:output_type -> memos.api.v1.MemoShare
28, // 66: memos.api.v1.MemoService.ListMemoShares:output_type -> memos.api.v1.ListMemoSharesResponse 28, // 66: memos.api.v1.MemoService.ListMemoShares:output_type -> memos.api.v1.ListMemoSharesResponse
41, // 67: memos.api.v1.MemoService.DeleteMemoShare:output_type -> google.protobuf.Empty 41, // 67: memos.api.v1.MemoService.DeleteMemoShare:output_type -> google.protobuf.Empty
3, // 68: memos.api.v1.MemoService.GetMemoByShare:output_type -> memos.api.v1.Memo 3, // 68: memos.api.v1.MemoService.GetSharedMemo:output_type -> memos.api.v1.Memo
34, // 69: memos.api.v1.MemoService.GetLinkMetadata:output_type -> memos.api.v1.LinkMetadata 34, // 69: memos.api.v1.MemoService.GetLinkMetadata:output_type -> memos.api.v1.LinkMetadata
33, // 70: memos.api.v1.MemoService.BatchGetLinkMetadata:output_type -> memos.api.v1.BatchGetLinkMetadataResponse 33, // 70: memos.api.v1.MemoService.BatchGetLinkMetadata:output_type -> memos.api.v1.BatchGetLinkMetadataResponse
51, // [51:71] is the sub-list for method output_type 51, // [51:71] is the sub-list for method output_type

View file

@ -852,42 +852,42 @@ func local_request_MemoService_DeleteMemoShare_0(ctx context.Context, marshaler
return msg, metadata, err return msg, metadata, err
} }
func request_MemoService_GetMemoByShare_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func request_MemoService_GetSharedMemo_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq GetMemoByShareRequest protoReq GetSharedMemoRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
err error err error
) )
if req.Body != nil { if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body) _, _ = io.Copy(io.Discard, req.Body)
} }
val, ok := pathParams["share_id"] val, ok := pathParams["share_token"]
if !ok { if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "share_id") return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "share_token")
} }
protoReq.ShareId, err = runtime.String(val) protoReq.ShareToken, err = runtime.String(val)
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "share_id", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "share_token", err)
} }
msg, err := client.GetMemoByShare(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) msg, err := client.GetSharedMemo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err return msg, metadata, err
} }
func local_request_MemoService_GetMemoByShare_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { func local_request_MemoService_GetSharedMemo_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var ( var (
protoReq GetMemoByShareRequest protoReq GetSharedMemoRequest
metadata runtime.ServerMetadata metadata runtime.ServerMetadata
err error err error
) )
val, ok := pathParams["share_id"] val, ok := pathParams["share_token"]
if !ok { if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "share_id") return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "share_token")
} }
protoReq.ShareId, err = runtime.String(val) protoReq.ShareToken, err = runtime.String(val)
if err != nil { if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "share_id", err) return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "share_token", err)
} }
msg, err := server.GetMemoByShare(ctx, &protoReq) msg, err := server.GetSharedMemo(ctx, &protoReq)
return msg, metadata, err return msg, metadata, err
} }
@ -1299,25 +1299,25 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
} }
forward_MemoService_DeleteMemoShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_MemoService_DeleteMemoShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodGet, pattern_MemoService_GetMemoByShare_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_MemoService_GetSharedMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
var stream runtime.ServerTransportStream var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.MemoService/GetMemoByShare", runtime.WithHTTPPathPattern("/api/v1/shares/{share_id}")) annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v1.MemoService/GetSharedMemo", runtime.WithHTTPPathPattern("/api/v1/shares/{share_token}/memo"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := local_request_MemoService_GetMemoByShare_0(annotatedContext, inboundMarshaler, server, req, pathParams) resp, md, err := local_request_MemoService_GetSharedMemo_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_MemoService_GetMemoByShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_MemoService_GetSharedMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodGet, pattern_MemoService_GetLinkMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_MemoService_GetLinkMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
@ -1688,22 +1688,22 @@ func RegisterMemoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
} }
forward_MemoService_DeleteMemoShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_MemoService_DeleteMemoShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodGet, pattern_MemoService_GetMemoByShare_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_MemoService_GetSharedMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.MemoService/GetMemoByShare", runtime.WithHTTPPathPattern("/api/v1/shares/{share_id}")) annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/memos.api.v1.MemoService/GetSharedMemo", runtime.WithHTTPPathPattern("/api/v1/shares/{share_token}/memo"))
if err != nil { if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return return
} }
resp, md, err := request_MemoService_GetMemoByShare_0(annotatedContext, inboundMarshaler, client, req, pathParams) resp, md, err := request_MemoService_GetSharedMemo_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil { if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return return
} }
forward_MemoService_GetMemoByShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) forward_MemoService_GetSharedMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
}) })
mux.Handle(http.MethodGet, pattern_MemoService_GetLinkMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle(http.MethodGet, pattern_MemoService_GetLinkMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
@ -1760,7 +1760,7 @@ var (
pattern_MemoService_CreateMemoShare_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "memos", "parent", "shares"}, "")) pattern_MemoService_CreateMemoShare_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "memos", "parent", "shares"}, ""))
pattern_MemoService_ListMemoShares_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "memos", "parent", "shares"}, "")) pattern_MemoService_ListMemoShares_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v1", "memos", "parent", "shares"}, ""))
pattern_MemoService_DeleteMemoShare_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "memos", "shares", "name"}, "")) pattern_MemoService_DeleteMemoShare_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 1, 0, 4, 4, 5, 4}, []string{"api", "v1", "memos", "shares", "name"}, ""))
pattern_MemoService_GetMemoByShare_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "shares", "share_id"}, "")) pattern_MemoService_GetSharedMemo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v1", "shares", "share_token", "memo"}, ""))
pattern_MemoService_GetLinkMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v1", "memos", "-", "linkMetadata"}, "")) pattern_MemoService_GetLinkMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v1", "memos", "-", "linkMetadata"}, ""))
pattern_MemoService_BatchGetLinkMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v1", "memos", "-", "linkMetadata"}, "batchGet")) pattern_MemoService_BatchGetLinkMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v1", "memos", "-", "linkMetadata"}, "batchGet"))
) )
@ -1783,7 +1783,7 @@ var (
forward_MemoService_CreateMemoShare_0 = runtime.ForwardResponseMessage forward_MemoService_CreateMemoShare_0 = runtime.ForwardResponseMessage
forward_MemoService_ListMemoShares_0 = runtime.ForwardResponseMessage forward_MemoService_ListMemoShares_0 = runtime.ForwardResponseMessage
forward_MemoService_DeleteMemoShare_0 = runtime.ForwardResponseMessage forward_MemoService_DeleteMemoShare_0 = runtime.ForwardResponseMessage
forward_MemoService_GetMemoByShare_0 = runtime.ForwardResponseMessage forward_MemoService_GetSharedMemo_0 = runtime.ForwardResponseMessage
forward_MemoService_GetLinkMetadata_0 = runtime.ForwardResponseMessage forward_MemoService_GetLinkMetadata_0 = runtime.ForwardResponseMessage
forward_MemoService_BatchGetLinkMetadata_0 = runtime.ForwardResponseMessage forward_MemoService_BatchGetLinkMetadata_0 = runtime.ForwardResponseMessage
) )

View file

@ -37,7 +37,7 @@ const (
MemoService_CreateMemoShare_FullMethodName = "/memos.api.v1.MemoService/CreateMemoShare" MemoService_CreateMemoShare_FullMethodName = "/memos.api.v1.MemoService/CreateMemoShare"
MemoService_ListMemoShares_FullMethodName = "/memos.api.v1.MemoService/ListMemoShares" MemoService_ListMemoShares_FullMethodName = "/memos.api.v1.MemoService/ListMemoShares"
MemoService_DeleteMemoShare_FullMethodName = "/memos.api.v1.MemoService/DeleteMemoShare" MemoService_DeleteMemoShare_FullMethodName = "/memos.api.v1.MemoService/DeleteMemoShare"
MemoService_GetMemoByShare_FullMethodName = "/memos.api.v1.MemoService/GetMemoByShare" MemoService_GetSharedMemo_FullMethodName = "/memos.api.v1.MemoService/GetSharedMemo"
MemoService_GetLinkMetadata_FullMethodName = "/memos.api.v1.MemoService/GetLinkMetadata" MemoService_GetLinkMetadata_FullMethodName = "/memos.api.v1.MemoService/GetLinkMetadata"
MemoService_BatchGetLinkMetadata_FullMethodName = "/memos.api.v1.MemoService/BatchGetLinkMetadata" MemoService_BatchGetLinkMetadata_FullMethodName = "/memos.api.v1.MemoService/BatchGetLinkMetadata"
) )
@ -87,9 +87,9 @@ type MemoServiceClient interface {
ListMemoShares(ctx context.Context, in *ListMemoSharesRequest, opts ...grpc.CallOption) (*ListMemoSharesResponse, error) ListMemoShares(ctx context.Context, in *ListMemoSharesRequest, opts ...grpc.CallOption) (*ListMemoSharesResponse, error)
// DeleteMemoShare revokes a share link. Requires authentication as the memo creator. // DeleteMemoShare revokes a share link. Requires authentication as the memo creator.
DeleteMemoShare(ctx context.Context, in *DeleteMemoShareRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) DeleteMemoShare(ctx context.Context, in *DeleteMemoShareRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
// GetMemoByShare resolves a share token to its memo. No authentication required. // GetSharedMemo resolves a share token to its memo. No authentication required.
// Returns NOT_FOUND if the token is invalid or expired. // Returns NOT_FOUND if the token is invalid or expired.
GetMemoByShare(ctx context.Context, in *GetMemoByShareRequest, opts ...grpc.CallOption) (*Memo, error) GetSharedMemo(ctx context.Context, in *GetSharedMemoRequest, opts ...grpc.CallOption) (*Memo, error)
// GetLinkMetadata gets metadata for a link. // GetLinkMetadata gets metadata for a link.
GetLinkMetadata(ctx context.Context, in *GetLinkMetadataRequest, opts ...grpc.CallOption) (*LinkMetadata, error) GetLinkMetadata(ctx context.Context, in *GetLinkMetadataRequest, opts ...grpc.CallOption) (*LinkMetadata, error)
// BatchGetLinkMetadata gets metadata for links. // BatchGetLinkMetadata gets metadata for links.
@ -274,10 +274,10 @@ func (c *memoServiceClient) DeleteMemoShare(ctx context.Context, in *DeleteMemoS
return out, nil return out, nil
} }
func (c *memoServiceClient) GetMemoByShare(ctx context.Context, in *GetMemoByShareRequest, opts ...grpc.CallOption) (*Memo, error) { func (c *memoServiceClient) GetSharedMemo(ctx context.Context, in *GetSharedMemoRequest, opts ...grpc.CallOption) (*Memo, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(Memo) out := new(Memo)
err := c.cc.Invoke(ctx, MemoService_GetMemoByShare_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, MemoService_GetSharedMemo_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -349,9 +349,9 @@ type MemoServiceServer interface {
ListMemoShares(context.Context, *ListMemoSharesRequest) (*ListMemoSharesResponse, error) ListMemoShares(context.Context, *ListMemoSharesRequest) (*ListMemoSharesResponse, error)
// DeleteMemoShare revokes a share link. Requires authentication as the memo creator. // DeleteMemoShare revokes a share link. Requires authentication as the memo creator.
DeleteMemoShare(context.Context, *DeleteMemoShareRequest) (*emptypb.Empty, error) DeleteMemoShare(context.Context, *DeleteMemoShareRequest) (*emptypb.Empty, error)
// GetMemoByShare resolves a share token to its memo. No authentication required. // GetSharedMemo resolves a share token to its memo. No authentication required.
// Returns NOT_FOUND if the token is invalid or expired. // Returns NOT_FOUND if the token is invalid or expired.
GetMemoByShare(context.Context, *GetMemoByShareRequest) (*Memo, error) GetSharedMemo(context.Context, *GetSharedMemoRequest) (*Memo, error)
// GetLinkMetadata gets metadata for a link. // GetLinkMetadata gets metadata for a link.
GetLinkMetadata(context.Context, *GetLinkMetadataRequest) (*LinkMetadata, error) GetLinkMetadata(context.Context, *GetLinkMetadataRequest) (*LinkMetadata, error)
// BatchGetLinkMetadata gets metadata for links. // BatchGetLinkMetadata gets metadata for links.
@ -417,8 +417,8 @@ func (UnimplementedMemoServiceServer) ListMemoShares(context.Context, *ListMemoS
func (UnimplementedMemoServiceServer) DeleteMemoShare(context.Context, *DeleteMemoShareRequest) (*emptypb.Empty, error) { func (UnimplementedMemoServiceServer) DeleteMemoShare(context.Context, *DeleteMemoShareRequest) (*emptypb.Empty, error) {
return nil, status.Error(codes.Unimplemented, "method DeleteMemoShare not implemented") return nil, status.Error(codes.Unimplemented, "method DeleteMemoShare not implemented")
} }
func (UnimplementedMemoServiceServer) GetMemoByShare(context.Context, *GetMemoByShareRequest) (*Memo, error) { func (UnimplementedMemoServiceServer) GetSharedMemo(context.Context, *GetSharedMemoRequest) (*Memo, error) {
return nil, status.Error(codes.Unimplemented, "method GetMemoByShare not implemented") return nil, status.Error(codes.Unimplemented, "method GetSharedMemo not implemented")
} }
func (UnimplementedMemoServiceServer) GetLinkMetadata(context.Context, *GetLinkMetadataRequest) (*LinkMetadata, error) { func (UnimplementedMemoServiceServer) GetLinkMetadata(context.Context, *GetLinkMetadataRequest) (*LinkMetadata, error) {
return nil, status.Error(codes.Unimplemented, "method GetLinkMetadata not implemented") return nil, status.Error(codes.Unimplemented, "method GetLinkMetadata not implemented")
@ -753,20 +753,20 @@ func _MemoService_DeleteMemoShare_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _MemoService_GetMemoByShare_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _MemoService_GetSharedMemo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetMemoByShareRequest) in := new(GetSharedMemoRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(MemoServiceServer).GetMemoByShare(ctx, in) return srv.(MemoServiceServer).GetSharedMemo(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: MemoService_GetMemoByShare_FullMethodName, FullMethod: MemoService_GetSharedMemo_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MemoServiceServer).GetMemoByShare(ctx, req.(*GetMemoByShareRequest)) return srv.(MemoServiceServer).GetSharedMemo(ctx, req.(*GetSharedMemoRequest))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
@ -883,8 +883,8 @@ var MemoService_ServiceDesc = grpc.ServiceDesc{
Handler: _MemoService_DeleteMemoShare_Handler, Handler: _MemoService_DeleteMemoShare_Handler,
}, },
{ {
MethodName: "GetMemoByShare", MethodName: "GetSharedMemo",
Handler: _MemoService_GetMemoByShare_Handler, Handler: _MemoService_GetSharedMemo_Handler,
}, },
{ {
MethodName: "GetLinkMetadata", MethodName: "GetLinkMetadata",

View file

@ -1266,18 +1266,18 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/Status' $ref: '#/components/schemas/Status'
/api/v1/shares/{shareId}: /api/v1/shares/{shareToken}/memo:
get: get:
tags: tags:
- MemoService - MemoService
description: |- description: |-
GetMemoByShare resolves a share token to its memo. No authentication required. GetSharedMemo resolves a share token to its memo. No authentication required.
Returns NOT_FOUND if the token is invalid or expired. Returns NOT_FOUND if the token is invalid or expired.
operationId: MemoService_GetMemoByShare operationId: MemoService_GetSharedMemo
parameters: parameters:
- name: shareId - name: shareToken
in: path in: path
description: Required. The share token extracted from the share URL (/s/{share_id}). description: Required. The opaque bearer token extracted from the share URL.
required: true required: true
schema: schema:
type: string type: string

View file

@ -37,7 +37,7 @@ var PublicMethods = map[string]struct{}{
"/memos.api.v1.MemoService/BatchGetLinkMetadata": {}, "/memos.api.v1.MemoService/BatchGetLinkMetadata": {},
// Memo sharing - share-token endpoints require no authentication // Memo sharing - share-token endpoints require no authentication
"/memos.api.v1.MemoService/GetMemoByShare": {}, "/memos.api.v1.MemoService/GetSharedMemo": {},
} }
// IsPublicMethod checks if a procedure path is public (no authentication required). // IsPublicMethod checks if a procedure path is public (no authentication required).
@ -70,7 +70,7 @@ var AuthBootstrapMethods = map[string]struct{}{
"/memos.api.v1.UserService/CreateUser": {}, "/memos.api.v1.UserService/CreateUser": {},
// Memo sharing - share-token access stays public even on a private instance. // Memo sharing - share-token access stays public even on a private instance.
"/memos.api.v1.MemoService/GetMemoByShare": {}, "/memos.api.v1.MemoService/GetSharedMemo": {},
} }
// IsAuthBootstrapMethod reports whether an anonymous request to procedure is one // IsAuthBootstrapMethod reports whether an anonymous request to procedure is one

View file

@ -112,7 +112,7 @@ func TestAuthBootstrapClassification(t *testing.T) {
"/memos.api.v1.InstanceService/GetInstanceSetting", "/memos.api.v1.InstanceService/GetInstanceSetting",
"/memos.api.v1.InstanceService/BatchGetInstanceSettings", "/memos.api.v1.InstanceService/BatchGetInstanceSettings",
"/memos.api.v1.IdentityProviderService/ListIdentityProviders", "/memos.api.v1.IdentityProviderService/ListIdentityProviders",
"/memos.api.v1.MemoService/GetMemoByShare", "/memos.api.v1.MemoService/GetSharedMemo",
} }
for _, method := range bootstrap { for _, method := range bootstrap {
t.Run("bootstrap/"+method, func(t *testing.T) { t.Run("bootstrap/"+method, func(t *testing.T) {

View file

@ -25,7 +25,7 @@ func TestAuthorizerCheckAccess(t *testing.T) {
publicMethod = "/memos.api.v1.MemoService/ListMemos" publicMethod = "/memos.api.v1.MemoService/ListMemos"
bootstrapMethod = "/memos.api.v1.AuthService/SignIn" bootstrapMethod = "/memos.api.v1.AuthService/SignIn"
createUser = "/memos.api.v1.UserService/CreateUser" createUser = "/memos.api.v1.UserService/CreateUser"
shareMethod = "/memos.api.v1.MemoService/GetMemoByShare" shareMethod = "/memos.api.v1.MemoService/GetSharedMemo"
) )
cases := []struct { cases := []struct {

View file

@ -439,8 +439,8 @@ func (s *ConnectServiceHandler) DeleteMemoShare(ctx context.Context, req *connec
return connect.NewResponse(resp), nil return connect.NewResponse(resp), nil
} }
func (s *ConnectServiceHandler) GetMemoByShare(ctx context.Context, req *connect.Request[v1pb.GetMemoByShareRequest]) (*connect.Response[v1pb.Memo], error) { func (s *ConnectServiceHandler) GetSharedMemo(ctx context.Context, req *connect.Request[v1pb.GetSharedMemoRequest]) (*connect.Response[v1pb.Memo], error) {
resp, err := s.APIV1Service.GetMemoByShare(ctx, req.Msg) resp, err := s.APIV1Service.GetSharedMemo(ctx, req.Msg)
if err != nil { if err != nil {
return nil, convertGRPCError(err) return nil, convertGRPCError(err)
} }

View file

@ -148,10 +148,10 @@ func (s *APIV1Service) DeleteMemoShare(ctx context.Context, request *v1pb.Delete
return &emptypb.Empty{}, nil return &emptypb.Empty{}, nil
} }
// GetMemoByShare resolves a share token to its memo. No authentication required. // GetSharedMemo resolves a share token to its memo. No authentication required.
// Returns NOT_FOUND for invalid or expired tokens (no information leakage). // Returns NOT_FOUND for invalid or expired tokens (no information leakage).
func (s *APIV1Service) GetMemoByShare(ctx context.Context, request *v1pb.GetMemoByShareRequest) (*v1pb.Memo, error) { func (s *APIV1Service) GetSharedMemo(ctx context.Context, request *v1pb.GetSharedMemoRequest) (*v1pb.Memo, error) {
ms, err := s.getActiveMemoShare(ctx, request.ShareId) ms, err := s.getActiveMemoShare(ctx, request.ShareToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -26,10 +26,10 @@ func TestAuthorizerPrivateInstanceRegistration(t *testing.T) {
authorizer := apiv1.NewAuthorizer(ts.Store, ts.Secret, &profile.Profile{InstanceURL: ""}) authorizer := apiv1.NewAuthorizer(ts.Store, ts.Secret, &profile.Profile{InstanceURL: ""})
const ( const (
createUser = "/memos.api.v1.UserService/CreateUser" createUser = "/memos.api.v1.UserService/CreateUser"
signIn = "/memos.api.v1.AuthService/SignIn" signIn = "/memos.api.v1.AuthService/SignIn"
listMemos = "/memos.api.v1.MemoService/ListMemos" listMemos = "/memos.api.v1.MemoService/ListMemos"
getMemoShare = "/memos.api.v1.MemoService/GetMemoByShare" getSharedMemo = "/memos.api.v1.MemoService/GetSharedMemo"
) )
// Anonymous request with no Authorization header resolves to no identity. // Anonymous request with no Authorization header resolves to no identity.
@ -38,7 +38,7 @@ func TestAuthorizerPrivateInstanceRegistration(t *testing.T) {
// Registration and other bootstrap methods are allowed; browsing is still gated. // Registration and other bootstrap methods are allowed; browsing is still gated.
require.NoError(t, authorizer.CheckAccess(ctx, createUser, nil)) require.NoError(t, authorizer.CheckAccess(ctx, createUser, nil))
require.NoError(t, authorizer.CheckAccess(ctx, signIn, nil)) require.NoError(t, authorizer.CheckAccess(ctx, signIn, nil))
require.NoError(t, authorizer.CheckAccess(ctx, getMemoShare, nil)) require.NoError(t, authorizer.CheckAccess(ctx, getSharedMemo, nil))
require.ErrorIs(t, authorizer.CheckAccess(ctx, listMemos, nil), apiv1.ErrUnauthenticated) require.ErrorIs(t, authorizer.CheckAccess(ctx, listMemos, nil), apiv1.ErrUnauthenticated)
// Once a user exists, CreateUser remains reachable so UserService can enforce // Once a user exists, CreateUser remains reachable so UserService can enforce

View file

@ -59,14 +59,14 @@ func TestDeleteMemoShare_VerifiesShareBelongsToMemo(t *testing.T) {
require.Error(t, err) require.Error(t, err)
require.Equal(t, codes.NotFound, status.Code(err)) require.Equal(t, codes.NotFound, status.Code(err))
sharedMemo, err := ts.Service.GetMemoByShare(ctx, &apiv1.GetMemoByShareRequest{ sharedMemo, err := ts.Service.GetSharedMemo(ctx, &apiv1.GetSharedMemoRequest{
ShareId: shareToken, ShareToken: shareToken,
}) })
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, memoTwo.Name, sharedMemo.Name) require.Equal(t, memoTwo.Name, sharedMemo.Name)
} }
func TestGetMemoByShare_IncludesReactions(t *testing.T) { func TestGetSharedMemo_IncludesReactions(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ts := NewTestService(t) ts := NewTestService(t)
@ -101,8 +101,8 @@ func TestGetMemoByShare_IncludesReactions(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
shareToken := share.Name[strings.LastIndex(share.Name, "/")+1:] shareToken := share.Name[strings.LastIndex(share.Name, "/")+1:]
sharedMemo, err := ts.Service.GetMemoByShare(ctx, &apiv1.GetMemoByShareRequest{ sharedMemo, err := ts.Service.GetSharedMemo(ctx, &apiv1.GetSharedMemoRequest{
ShareId: shareToken, ShareToken: shareToken,
}) })
require.NoError(t, err) require.NoError(t, err)
require.Len(t, sharedMemo.Reactions, 1) require.Len(t, sharedMemo.Reactions, 1)
@ -110,7 +110,7 @@ func TestGetMemoByShare_IncludesReactions(t *testing.T) {
require.Equal(t, memo.Name, sharedMemo.Reactions[0].ContentId) require.Equal(t, memo.Name, sharedMemo.Reactions[0].ContentId)
} }
func TestGetMemoByShare_SkipsReactionsWithMissingCreators(t *testing.T) { func TestGetSharedMemo_SkipsReactionsWithMissingCreators(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ts := NewTestService(t) ts := NewTestService(t)
@ -151,27 +151,27 @@ func TestGetMemoByShare_SkipsReactionsWithMissingCreators(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
shareToken := share.Name[strings.LastIndex(share.Name, "/")+1:] shareToken := share.Name[strings.LastIndex(share.Name, "/")+1:]
sharedMemo, err := ts.Service.GetMemoByShare(ctx, &apiv1.GetMemoByShareRequest{ sharedMemo, err := ts.Service.GetSharedMemo(ctx, &apiv1.GetSharedMemoRequest{
ShareId: shareToken, ShareToken: shareToken,
}) })
require.NoError(t, err) require.NoError(t, err)
require.Empty(t, sharedMemo.Reactions) require.Empty(t, sharedMemo.Reactions)
} }
func TestGetMemoByShare_ReturnsNotFoundForUnknownShare(t *testing.T) { func TestGetSharedMemo_ReturnsNotFoundForUnknownShare(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ts := NewTestService(t) ts := NewTestService(t)
defer ts.Cleanup() defer ts.Cleanup()
_, err := ts.Service.GetMemoByShare(ctx, &apiv1.GetMemoByShareRequest{ _, err := ts.Service.GetSharedMemo(ctx, &apiv1.GetSharedMemoRequest{
ShareId: "missing-share-token", ShareToken: "missing-share-token",
}) })
require.Error(t, err) require.Error(t, err)
require.Equal(t, codes.NotFound, status.Code(err)) require.Equal(t, codes.NotFound, status.Code(err))
} }
func TestGetMemoByShare_ReturnsNotFoundForExpiredShare(t *testing.T) { func TestGetSharedMemo_ReturnsNotFoundForExpiredShare(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ts := NewTestService(t) ts := NewTestService(t)
@ -198,14 +198,14 @@ func TestGetMemoByShare_ReturnsNotFoundForExpiredShare(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
_, err = ts.Service.GetMemoByShare(ctx, &apiv1.GetMemoByShareRequest{ _, err = ts.Service.GetSharedMemo(ctx, &apiv1.GetSharedMemoRequest{
ShareId: expiredShare.UID, ShareToken: expiredShare.UID,
}) })
require.Error(t, err) require.Error(t, err)
require.Equal(t, codes.NotFound, status.Code(err)) require.Equal(t, codes.NotFound, status.Code(err))
} }
func TestGetMemoByShare_ReturnsNotFoundForArchivedMemo(t *testing.T) { func TestGetSharedMemo_ReturnsNotFoundForArchivedMemo(t *testing.T) {
ctx := context.Background() ctx := context.Background()
ts := NewTestService(t) ts := NewTestService(t)
@ -242,8 +242,8 @@ func TestGetMemoByShare_ReturnsNotFoundForArchivedMemo(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
shareToken := share.Name[strings.LastIndex(share.Name, "/")+1:] shareToken := share.Name[strings.LastIndex(share.Name, "/")+1:]
_, err = ts.Service.GetMemoByShare(ctx, &apiv1.GetMemoByShareRequest{ _, err = ts.Service.GetSharedMemo(ctx, &apiv1.GetSharedMemoRequest{
ShareId: shareToken, ShareToken: shareToken,
}) })
require.Error(t, err) require.Error(t, err)
require.Equal(t, codes.NotFound, status.Code(err)) require.Equal(t, codes.NotFound, status.Code(err))

View file

@ -7,7 +7,7 @@ import type { MemoShare } from "@/types/proto/api/v1/memo_service_pb";
import { import {
CreateMemoShareRequestSchema, CreateMemoShareRequestSchema,
DeleteMemoShareRequestSchema, DeleteMemoShareRequestSchema,
GetMemoByShareRequestSchema, GetSharedMemoRequestSchema,
ListMemoSharesRequestSchema, ListMemoSharesRequestSchema,
MemoShareSchema, MemoShareSchema,
} from "@/types/proto/api/v1/memo_service_pb"; } from "@/types/proto/api/v1/memo_service_pb";
@ -16,7 +16,7 @@ import {
export const memoShareKeys = { export const memoShareKeys = {
all: ["memo-shares"] as const, all: ["memo-shares"] as const,
list: (memoName: string) => [...memoShareKeys.all, "list", memoName] as const, list: (memoName: string) => [...memoShareKeys.all, "list", memoName] as const,
byShare: (shareId: string) => [...memoShareKeys.all, "by-share", shareId] as const, byShare: (shareToken: string) => [...memoShareKeys.all, "by-share", shareToken] as const,
}; };
/** Lists all active share links for a memo (creator-only). */ /** Lists all active share links for a memo (creator-only). */
@ -63,14 +63,14 @@ export function useDeleteMemoShare() {
} }
/** Resolves a share token to its memo. Used by the public SharedMemo page. */ /** Resolves a share token to its memo. Used by the public SharedMemo page. */
export function useSharedMemo(shareId: string, options?: { enabled?: boolean }) { export function useSharedMemo(shareToken: string, options?: { enabled?: boolean }) {
return useQuery({ return useQuery({
queryKey: memoShareKeys.byShare(shareId), queryKey: memoShareKeys.byShare(shareToken),
queryFn: async () => { queryFn: async () => {
const memo = await memoServiceClient.getMemoByShare(create(GetMemoByShareRequestSchema, { shareId })); const memo = await memoServiceClient.getSharedMemo(create(GetSharedMemoRequestSchema, { shareToken }));
return memo; return memo;
}, },
enabled: options?.enabled ?? !!shareId, enabled: options?.enabled ?? !!shareToken,
retry: false, // Don't retry NOT_FOUND — the link is invalid or expired retry: false, // Don't retry NOT_FOUND — the link is invalid or expired
}); });
} }

File diff suppressed because one or more lines are too long