22 Commits

Author SHA1 Message Date
d939bb8250 chore: update version to 0.4.2 2023-08-16 19:15:44 +08:00
946548b33a fix: access token checks 2023-08-16 18:55:11 +08:00
d97a7e736d chore: add extension link to readme 2023-08-16 09:18:54 +08:00
e5d5ba5cbc chore: update extension version 2023-08-16 08:54:51 +08:00
ce4232c9f5 fix: create shortcut dialog height 2023-08-15 22:24:26 +08:00
bc6a72561c chore: update resource path setting checks 2023-08-15 21:38:02 +08:00
b9e5e7f2af feat: add resource service 2023-08-15 00:02:40 +08:00
96ab5b226d chore: fix method name 2023-08-13 00:00:14 +08:00
9c6f85e938 feat: add logo to extension 2023-08-12 00:47:08 +08:00
f1e3eace1a feat: add omnibox to extension 2023-08-11 00:26:04 +08:00
6f26523a11 chore: update extension docs 2023-08-11 00:20:39 +08:00
304a29a18c chore: upgrade extension version 2023-08-10 22:34:44 +08:00
3e5fa5573e chore: update options initial state check 2023-08-10 22:30:11 +08:00
93ed3c81ff fix: max width 2023-08-10 22:29:54 +08:00
0efd495f56 feat: add create shortcut button 2023-08-10 22:23:22 +08:00
ae56f6df8c chore: fix create shortcut 2023-08-10 22:23:12 +08:00
df51720310 chore: add server test 2023-08-10 20:57:43 +08:00
1194099667 feat: add create shortcut api 2023-08-09 23:31:52 +08:00
e936aaced1 chore: add create user api 2023-08-09 23:20:01 +08:00
0ee999a30a chore: update extension manifest 2023-08-09 09:04:41 +08:00
1211136037 chore: update resources 2023-08-09 09:04:13 +08:00
73061034b2 chore: update readme 2023-08-08 23:58:15 +08:00
59 changed files with 2466 additions and 314 deletions

View File

@ -17,6 +17,7 @@
- Create customizable `/s/` short links for any URL.
- Share short links privately or with teammates.
- View analytics on link traffic and sources.
- Easy access to your shortcuts with browser extension.
- Open source self-hosted solution.
## Deploy with Docker in seconds
@ -26,3 +27,15 @@ docker run -d --name slash -p 5231:5231 -v ~/.slash/:/var/opt/slash yourselfhost
```
Learn more in [Self-hosting Slash with Docker](https://github.com/boojack/slash/blob/main/docs/install.md).
## Browser Extension
Slash provides a browser extension to help you use your shortcuts in the search bar to go to the corresponding URL.
![browser-extension-example](./resources/browser-extension-example.png)
### Chromium based browsers
For Chromium based browsers(Chrome, Edge, Arc, ...), you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg).
Learn more in [The Browser Extension of Slash](https://github.com/boojack/slash/blob/main/docs/install-browser-extension.md).

View File

@ -71,7 +71,7 @@ func JWTMiddleware(s *APIV1Service, next echo.HandlerFunc, secret string) echo.H
token := findAccessToken(c)
if token == "" {
// When the request is not authenticated, we allow the user to access the shortcut endpoints for those public shortcuts.
if util.HasPrefixes(path, "/s/*") && method == http.MethodGet {
if util.HasPrefixes(path, "/s/") && method == http.MethodGet {
return next(c)
}
return echo.NewHTTPError(http.StatusUnauthorized, "Missing access token")

View File

@ -90,7 +90,7 @@ func (s *APIV1Service) registerShortcutRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("malformatted post shortcut request, err: %s", err)).SetInternal(err)
}
shortcut, err := s.Store.CreateShortcut(ctx, &storepb.Shortcut{
shortcut := &storepb.Shortcut{
CreatorId: userID,
Name: strings.ToLower(create.Name),
Link: create.Link,
@ -98,12 +98,16 @@ func (s *APIV1Service) registerShortcutRoutes(g *echo.Group) {
Description: create.Description,
Visibility: convertVisibilityToStorepb(create.Visibility),
Tags: create.Tags,
OgMetadata: &storepb.OpenGraphMetadata{
OgMetadata: &storepb.OpenGraphMetadata{},
}
if create.OpenGraphMetadata != nil {
shortcut.OgMetadata = &storepb.OpenGraphMetadata{
Title: create.OpenGraphMetadata.Title,
Description: create.OpenGraphMetadata.Description,
Image: create.OpenGraphMetadata.Image,
},
})
}
}
shortcut, err := s.Store.CreateShortcut(ctx, shortcut)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to create shortcut, err: %s", err)).SetInternal(err)
}
@ -349,6 +353,8 @@ func convertVisibilityToStorepb(visibility Visibility) storepb.Visibility {
switch visibility {
case VisibilityPublic:
return storepb.Visibility_PUBLIC
case VisibilityWorkspace:
return storepb.Visibility_WORKSPACE
case VisibilityPrivate:
return storepb.Visibility_PRIVATE
default:

View File

@ -17,16 +17,6 @@ import (
"google.golang.org/grpc/status"
)
var authenticationAllowlistMethods = map[string]bool{}
// IsAuthenticationAllowed returns whether the method is exempted from authentication.
func IsAuthenticationAllowed(fullMethodName string) bool {
if strings.HasPrefix(fullMethodName, "/grpc.reflection") {
return true
}
return authenticationAllowlistMethods[fullMethodName]
}
// ContextKey is the key type of context value.
type ContextKey int
@ -63,11 +53,23 @@ func (in *GRPCAuthInterceptor) AuthenticationInterceptor(ctx context.Context, re
userID, err := in.authenticate(ctx, accessToken)
if err != nil {
if IsAuthenticationAllowed(serverInfo.FullMethod) {
if isUnauthorizeAllowedMethod(serverInfo.FullMethod) {
return handler(ctx, request)
}
return nil, err
}
user, err := in.Store.GetUser(ctx, &store.FindUser{
ID: &userID,
})
if err != nil {
return nil, errors.Wrap(err, "failed to get user")
}
if user == nil {
return nil, status.Errorf(codes.Unauthenticated, "user ID %q not exists in the access token", userID)
}
if isOnlyForAdminAllowedMethod(serverInfo.FullMethod) && user.Role != store.RoleAdmin {
return nil, status.Errorf(codes.PermissionDenied, "user ID %q is not admin", userID)
}
userAccessTokens, err := in.Store.GetUserAccessTokens(ctx, userID)
if err != nil {

22
api/v2/acl_config.go Normal file
View File

@ -0,0 +1,22 @@
package v2
import "strings"
var allowedMethodsWhenUnauthorized = map[string]bool{}
// isUnauthorizeAllowedMethod returns true if the method is allowed to be called when the user is not authorized.
func isUnauthorizeAllowedMethod(methodName string) bool {
if strings.HasPrefix(methodName, "/grpc.reflection") {
return true
}
return allowedMethodsWhenUnauthorized[methodName]
}
var allowedMethodsOnlyForAdmin = map[string]bool{
"/slash.api.v2.UserService/CreateUser": true,
}
// isOnlyForAdminAllowedMethod returns true if the method is allowed to be called only by admin.
func isOnlyForAdminAllowedMethod(methodName string) bool {
return allowedMethodsOnlyForAdmin[methodName]
}

View File

@ -6,8 +6,10 @@ import (
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
storepb "github.com/boojack/slash/proto/gen/store"
"github.com/boojack/slash/store"
"github.com/pkg/errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/encoding/protojson"
)
type ShortcutService struct {
@ -75,6 +77,60 @@ func (s *ShortcutService) GetShortcut(ctx context.Context, request *apiv2pb.GetS
return response, nil
}
func (s *ShortcutService) CreateShortcut(ctx context.Context, request *apiv2pb.CreateShortcutRequest) (*apiv2pb.CreateShortcutResponse, error) {
userID := ctx.Value(UserIDContextKey).(int32)
shortcut := &storepb.Shortcut{
CreatorId: userID,
Name: request.Shortcut.Name,
Link: request.Shortcut.Link,
Title: request.Shortcut.Title,
Tags: request.Shortcut.Tags,
Description: request.Shortcut.Description,
Visibility: storepb.Visibility(request.Shortcut.Visibility),
OgMetadata: &storepb.OpenGraphMetadata{},
}
if request.Shortcut.OgMetadata != nil {
shortcut.OgMetadata = &storepb.OpenGraphMetadata{
Title: request.Shortcut.OgMetadata.Title,
Description: request.Shortcut.OgMetadata.Description,
Image: request.Shortcut.OgMetadata.Image,
}
}
shortcut, err := s.Store.CreateShortcut(ctx, shortcut)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to create shortcut, err: %v", err)
}
if err := s.createShortcutCreateActivity(ctx, shortcut); err != nil {
return nil, status.Errorf(codes.Internal, "failed to create activity, err: %v", err)
}
response := &apiv2pb.CreateShortcutResponse{
Shortcut: convertShortcutFromStorepb(shortcut),
}
return response, nil
}
func (s *ShortcutService) createShortcutCreateActivity(ctx context.Context, shortcut *storepb.Shortcut) error {
payload := &storepb.ActivityShorcutCreatePayload{
ShortcutId: shortcut.Id,
}
payloadStr, err := protojson.Marshal(payload)
if err != nil {
return errors.Wrap(err, "Failed to marshal activity payload")
}
activity := &store.Activity{
CreatorID: shortcut.CreatorId,
Type: store.ActivityShortcutCreate,
Level: store.ActivityInfo,
Payload: string(payloadStr),
}
_, err = s.Store.CreateActivity(ctx, activity)
if err != nil {
return errors.Wrap(err, "Failed to create activity")
}
return nil
}
func convertShortcutFromStorepb(shortcut *storepb.Shortcut) *apiv2pb.Shortcut {
return &apiv2pb.Shortcut{
Id: shortcut.Id,

View File

@ -9,6 +9,7 @@ import (
"github.com/boojack/slash/store"
"github.com/golang-jwt/jwt/v4"
"github.com/pkg/errors"
"golang.org/x/crypto/bcrypt"
"golang.org/x/exp/slices"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@ -48,6 +49,27 @@ func (s *UserService) GetUser(ctx context.Context, request *apiv2pb.GetUserReque
return response, nil
}
func (s *UserService) CreateUser(ctx context.Context, request *apiv2pb.CreateUserRequest) (*apiv2pb.CreateUserResponse, error) {
passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to hash password: %v", err)
}
user, err := s.Store.CreateUser(ctx, &store.User{
Email: request.User.Email,
Nickname: request.User.Nickname,
Role: store.RoleUser,
PasswordHash: string(passwordHash),
})
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to create user: %v", err)
}
response := &apiv2pb.CreateUserResponse{
User: convertUserFromStore(user),
}
return response, nil
}
func (s *UserService) ListUserAccessTokens(ctx context.Context, request *apiv2pb.ListUserAccessTokensRequest) (*apiv2pb.ListUserAccessTokensResponse, error) {
userID := ctx.Value(UserIDContextKey).(int32)
if userID != request.Id {

View File

@ -4,6 +4,12 @@ Slash provides a browser extension to help you use your shortcuts in the search
## How to use
### Install the extension
For Chromuim based browsers, you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg).
For Firefox, we don't support the Firefox Add-ons platform yet. And we are working on it.
### Generate an access token
1. Go to your Slash instance and sign in with your account.
@ -16,14 +22,6 @@ Slash provides a browser extension to help you use your shortcuts in the search
![](./assets/extension-usage/copy-access-token.png)
### Install the extension
> **Note**: The extension is not published to the Chrome Web Store yet. You can install it from the source code.
For Chromuim based browsers, you can download the packed extension from the [resources](https://github.com/boojack/slash/tree/main/extension/resources).
For Firefox, we don't support the Firefox Add-ons platform yet. And we are working on it.
### Configure the extension
1. Click on the extension icon and click on the "Settings" button.

View File

@ -1,9 +1,8 @@
{
"name": "slash-extexnsion",
"name": "slash-extension",
"displayName": "Slash",
"version": "0.1.0",
"version": "0.1.3",
"description": "An open source, self-hosted bookmarks and link sharing platform. Save and share your links very easily.",
"author": "steven",
"scripts": {
"dev": "plasmo dev",
"build": "plasmo build",
@ -12,6 +11,7 @@
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix"
},
"dependencies": {
"@bufbuild/protobuf": "^1.3.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/joy": "5.0.0-beta.0",
@ -46,14 +46,11 @@
"typescript": "5.1.6"
},
"manifest": {
"host_permissions": [
"http://*/*",
"https://*/*"
],
"omnibox": {
"keyword": "s"
},
"permissions": [
"tabs",
"activeTab",
"scripting",
"storage"
]
}

View File

@ -5,6 +5,9 @@ settings:
excludeLinksFromLockfile: false
dependencies:
'@bufbuild/protobuf':
specifier: ^1.3.0
version: 1.3.0
'@emotion/react':
specifier: ^11.11.1
version: 11.11.1(@types/react@18.2.15)(react@18.2.0)
@ -339,6 +342,10 @@ packages:
'@babel/helper-validator-identifier': 7.22.5
to-fast-properties: 2.0.0
/@bufbuild/protobuf@1.3.0:
resolution: {integrity: sha512-G372ods0pLt46yxVRsnP/e2btVPuuzArcMPFpIDeIwiGPuuglEs9y75iG0HMvZgncsj5TvbYRWqbVyOe3PLCWQ==}
dev: false
/@emotion/babel-plugin@11.11.0:
resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==}
dependencies:

View File

@ -20,6 +20,15 @@ chrome.tabs.onUpdated.addListener(async (tabId, _, tab) => {
}
});
chrome.omnibox.onInputEntered.addListener(async (text) => {
const shortcuts = (await storage.getItem<Shortcut[]>("shortcuts")) || [];
const shortcut = shortcuts.find((shortcut) => shortcut.name === text);
if (!shortcut) {
return;
}
return chrome.tabs.update({ url: shortcut.link });
});
const getShortcutNameFromUrl = (urlString: string) => {
const matchResult = urlRegex.exec(urlString);
if (matchResult === null) {

View File

@ -0,0 +1,173 @@
import { Button, IconButton, Input, Modal, ModalDialog } from "@mui/joy";
import { useStorage } from "@plasmohq/storage/hook";
import axios from "axios";
import { useEffect, useState } from "react";
import { toast } from "react-hot-toast";
import { CreateShortcutResponse, OpenGraphMetadata, Visibility } from "@/types/proto/api/v2/shortcut_service_pb";
import Icon from "./Icon";
const generateTempName = (length = 6) => {
let result = "";
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const charactersLength = characters.length;
let counter = 0;
while (counter < length) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
counter += 1;
}
return result;
};
interface State {
name: string;
title: string;
link: string;
}
const CreateShortcutsButton = () => {
const [domain] = useStorage("domain");
const [accessToken] = useStorage("access_token");
const [shortcuts, setShortcuts] = useStorage("shortcuts");
const [state, setState] = useState<State>({
name: "",
title: "",
link: "",
});
const [isLoading, setIsLoading] = useState(false);
const [showModal, setShowModal] = useState(false);
useEffect(() => {
if (showModal) {
document.body.style.height = "384px";
} else {
document.body.style.height = "auto";
}
}, [showModal]);
const handleCreateShortcutButtonClick = async () => {
chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
if (tabs.length === 0) {
toast.error("No active tab found");
return;
}
const tab = tabs[0];
setState((state) => ({
...state,
name: generateTempName().toLowerCase() + "-temp",
title: tab.title || "",
link: tab.url || "",
}));
setShowModal(true);
});
};
const handleNameInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setState((state) => ({
...state,
name: e.target.value,
}));
};
const handleTitleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setState((state) => ({
...state,
title: e.target.value,
}));
};
const handleLinkInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setState((state) => ({
...state,
link: e.target.value,
}));
};
const handleSaveBtnClick = async () => {
if (isLoading) {
return;
}
if (!state.name) {
toast.error("Name is required");
return;
}
setIsLoading(true);
try {
const {
data: { shortcut },
} = await axios.post<CreateShortcutResponse>(
`${domain}/api/v2/shortcuts`,
{
name: state.name,
title: state.title,
link: state.link,
visibility: Visibility.PRIVATE,
ogMetadata: OpenGraphMetadata.fromJsonString("{}"),
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);
setShortcuts([shortcut, ...shortcuts]);
toast.success("Shortcut created successfully");
setShowModal(false);
} catch (error: any) {
console.error(error);
toast.error(error.response.data.message);
}
setIsLoading(false);
};
return (
<>
<IconButton color="primary" variant="solid" size="sm" onClick={() => handleCreateShortcutButtonClick()}>
<Icon.Plus className="w-5 h-auto" />
</IconButton>
<Modal container={() => document.body} open={showModal} onClose={() => setShowModal(false)}>
<ModalDialog>
<div className="w-full flex flex-row justify-between items-center mb-2">
<span className="text-base font-medium">Create Shortcut</span>
<Button size="sm" variant="plain" onClick={() => setShowModal(false)}>
<Icon.X className="w-5 h-auto text-gray-600" />
</Button>
</div>
<div className="overflow-x-hidden px-2 w-full flex flex-col justify-start items-center">
<div className="w-full flex flex-row justify-start items-center mb-2">
<span className="block w-16 shrink-0">Name</span>
<Input className="grow" type="text" placeholder="Unique shortcut name" value={state.name} onChange={handleNameInputChange} />
</div>
<div className="w-full flex flex-row justify-start items-center mb-2">
<span className="block w-16 shrink-0">Title</span>
<Input className="grow" type="text" placeholder="Shortcut title" value={state.title} onChange={handleTitleInputChange} />
</div>
<div className="w-full flex flex-row justify-start items-center mb-2">
<span className="block w-16 shrink-0">Link</span>
<Input
className="grow"
type="text"
placeholder="https://github.com/boojack/slash"
value={state.link}
onChange={handleLinkInputChange}
/>
</div>
<div className="w-full flex flex-row justify-end items-center mt-2 space-x-2">
<Button color="neutral" variant="plain" onClick={() => setShowModal(false)}>
Cancel
</Button>
<Button color="primary" disabled={isLoading} loading={isLoading} onClick={handleSaveBtnClick}>
Save
</Button>
</div>
</div>
</ModalDialog>
</Modal>
</>
);
};
export default CreateShortcutsButton;

View File

@ -0,0 +1,12 @@
import classNames from "classnames";
import LogoBase64 from "data-base64:../..//assets/icon.png";
interface Props {
className?: string;
}
const Logo = ({ className }: Props) => {
return <img className={classNames(className)} src={LogoBase64} alt="" />;
};
export default Logo;

View File

@ -1,17 +1,15 @@
import { Button } from "@mui/joy";
import { IconButton } from "@mui/joy";
import { useStorage } from "@plasmohq/storage/hook";
import axios from "axios";
import { useEffect, useState } from "react";
import { useEffect } from "react";
import { toast } from "react-hot-toast";
import { ListShortcutsResponse } from "@/types/proto/api/v2/shortcut_service_pb";
import "../style.css";
import Icon from "./Icon";
const PullShortcutsButton = () => {
const [domain] = useStorage("domain");
const [accessToken] = useStorage("access_token");
const [, setShortcuts] = useStorage("shortcuts");
const [isPulling, setIsPulling] = useState(false);
useEffect(() => {
if (domain && accessToken) {
@ -21,7 +19,6 @@ const PullShortcutsButton = () => {
const handlePullShortcuts = async (silence = false) => {
try {
setIsPulling(true);
const {
data: { shortcuts },
} = await axios.get<ListShortcutsResponse>(`${domain}/api/v2/shortcuts`, {
@ -36,13 +33,12 @@ const PullShortcutsButton = () => {
} catch (error) {
toast.error("Failed to pull shortcuts, error: " + error.message);
}
setIsPulling(false);
};
return (
<Button loading={isPulling} color="neutral" variant="plain" size="sm" onClick={() => handlePullShortcuts()}>
<IconButton color="neutral" variant="plain" size="sm" onClick={() => handlePullShortcuts()}>
<Icon.RefreshCcw className="w-4 h-auto" />
</Button>
</IconButton>
);
};

View File

@ -1,8 +1,12 @@
import { Button, Input } from "@mui/joy";
import type { Shortcut } from "./types/proto/api/v2/shortcut_service_pb";
import { Button, Divider, Input } from "@mui/joy";
import { useStorage } from "@plasmohq/storage/hook";
import { useEffect, useState } from "react";
import { Toaster, toast } from "react-hot-toast";
import Icon from "./components/Icon";
import Logo from "./components/Logo";
import PullShortcutsButton from "./components/PullShortcutsButton";
import ShortcutsContainer from "./components/ShortcutsContainer";
import "./style.css";
interface SettingState {
@ -17,6 +21,8 @@ const IndexOptions = () => {
domain,
accessToken,
});
const [shortcuts] = useStorage<Shortcut[]>("shortcuts", []);
const isInitialized = domain && accessToken;
useEffect(() => {
setSettingState({
@ -41,43 +47,82 @@ const IndexOptions = () => {
return (
<>
<div className="w-full">
<div className="w-full flex flex-row justify-center items-center">
<a
className="bg-yellow-100 mt-12 py-2 px-3 rounded-full border flex flex-row justify-start items-center cursor-pointer shadow hover:underline hover:text-blue-600"
href="https://github.com/boojack/slash#browser-extension"
target="_blank"
>
<Icon.HelpCircle className="w-4 h-auto" />
<span className="mx-1 text-sm">Need help? Check out the docs</span>
<Icon.ExternalLink className="w-4 h-auto" />
</a>
</div>
<div className="w-full max-w-lg mx-auto flex flex-col justify-start items-start mt-12">
<h2 className="flex flex-row justify-start items-center mb-6 font-mono">
<Icon.CircleSlash className="w-8 h-auto mr-2 text-gray-500" />
<span className="text-lg">Slash</span>
<h2 className="flex flex-row justify-start items-center mb-6 text-2xl">
<Logo className="w-10 h-auto mr-2" />
<span>Slash</span>
<span className="mx-2 text-gray-400">/</span>
<span className="text-lg">Setting</span>
<span>Setting</span>
</h2>
<div className="w-full flex flex-col justify-start items-start mb-4">
<span className="mb-2 text-base">Domain</span>
<div className="relative w-full">
<Input
className="w-full"
type="text"
placeholder="The domain of your Slash instance"
value={settingState.domain}
onChange={(e) => setPartialSettingState({ domain: e.target.value })}
/>
</div>
</div>
<div className="w-full flex flex-col justify-start items-start">
<span className="mb-2 text-base">Access Token</span>
<div className="relative w-full">
<Input
className="w-full"
type="text"
placeholder="The access token of your Slash instance"
value={settingState.accessToken}
onChange={(e) => setPartialSettingState({ accessToken: e.target.value })}
/>
<div className="w-full flex flex-col justify-start items-start mb-4">
<div className="mb-2 text-base w-full flex flex-row justify-between items-center">
<span>Domain</span>
{domain !== "" && (
<a
className="text-sm flex flex-row justify-start items-center hover:underline hover:text-blue-600"
href={domain}
target="_blank"
>
<span className="mr-1">Go to my Slash</span>
<Icon.ExternalLink className="w-4 h-auto" />
</a>
)}
</div>
<div className="relative w-full">
<Input
className="w-full"
type="text"
placeholder="The domain of your Slash instance"
value={settingState.domain}
onChange={(e) => setPartialSettingState({ domain: e.target.value })}
/>
</div>
</div>
<div className="w-full flex flex-col justify-start items-start">
<span className="mb-2 text-base">Access Token</span>
<div className="relative w-full">
<Input
className="w-full"
type="text"
placeholder="The access token of your Slash instance"
value={settingState.accessToken}
onChange={(e) => setPartialSettingState({ accessToken: e.target.value })}
/>
</div>
</div>
<div className="w-full mt-6">
<Button onClick={handleSaveSetting}>Save</Button>
</div>
</div>
<div className="w-full mt-6">
<Button onClick={handleSaveSetting}>Save</Button>
</div>
{isInitialized && (
<>
<Divider className="!my-6" />
<h2 className="flex flex-row justify-start items-center mb-4">
<span className="text-lg">Shortcuts</span>
<span className="text-gray-500 mr-1">({shortcuts.length})</span>
<PullShortcutsButton />
</h2>
<ShortcutsContainer />
</>
)}
</div>
</div>

View File

@ -1,10 +1,12 @@
import { Button } from "@mui/joy";
import { Button, Divider, IconButton } from "@mui/joy";
import { useStorage } from "@plasmohq/storage/hook";
import { Toaster } from "react-hot-toast";
import CreateShortcutsButton from "@/components/CreateShortcutsButton";
import Icon from "@/components/Icon";
import Logo from "@/components/Logo";
import PullShortcutsButton from "@/components/PullShortcutsButton";
import ShortcutsContainer from "@/components/ShortcutsContainer";
import { Shortcut } from "@/types/proto/api/v2/shortcut_service_pb";
import Icon from "./components/Icon";
import PullShortcutsButton from "./components/PullShortcutsButton";
import ShortcutsContainer from "./components/ShortcutsContainer";
import "./style.css";
const IndexPopup = () => {
@ -19,40 +21,69 @@ const IndexPopup = () => {
const handleRefreshButtonClick = () => {
chrome.runtime.reload();
chrome.browserAction.setPopup({ popup: "" });
};
return (
<>
<div className="w-full min-w-[480px] p-4">
<div className="w-full flex flex-row justify-between items-center text-sm">
<div className="flex flex-row justify-start items-center font-mono">
<Icon.CircleSlash className="w-5 h-auto mr-1 text-gray-500 -mt-0.5" />
<span className="font-mono">Slash</span>
<div className="w-full min-w-[512px] px-4 pt-4">
<div className="w-full flex flex-row justify-between items-center">
<div className="flex flex-row justify-start items-center">
<Logo className="w-6 h-auto mr-2" />
<span className="">Slash</span>
{isInitialized && (
<>
<span className="mx-1 text-gray-400">/</span>
<span>Shortcuts</span>
<span className="mr-1 text-gray-500">({shortcuts.length})</span>
<span className="text-gray-500 mr-0.5">({shortcuts.length})</span>
<PullShortcutsButton />
</>
)}
</div>
<div>
<Button size="sm" variant="plain" color="neutral" onClick={handleSettingButtonClick}>
<Icon.Settings className="w-5 h-auto" />
</Button>
</div>
<div>{isInitialized && <CreateShortcutsButton />}</div>
</div>
<div className="w-full mt-4">
{isInitialized ? (
shortcuts.length !== 0 ? (
<ShortcutsContainer />
) : (
<div className="w-full flex flex-col justify-center items-center">
<p>No shortcut found.</p>
<>
{shortcuts.length !== 0 ? (
<ShortcutsContainer />
) : (
<div className="w-full flex flex-col justify-center items-center">
<p>No shortcut found.</p>
</div>
)}
<Divider className="!mt-4 !mb-2 opacity-40" />
<div className="w-full flex flex-row justify-between items-center mb-2">
<div className="flex flex-row justify-start items-center">
<IconButton size="sm" variant="plain" color="neutral" onClick={handleSettingButtonClick}>
<Icon.Settings className="w-5 h-auto text-gray-500" />
</IconButton>
<IconButton
size="sm"
variant="plain"
color="neutral"
component="a"
href="https://github.com/boojack/slash"
target="_blank"
>
<Icon.Github className="w-5 h-auto text-gray-500" />
</IconButton>
</div>
<div className="flex flex-row justify-end items-center">
<a
className="text-sm flex flex-row justify-start items-center text-gray-500 hover:underline hover:text-blue-600"
href={domain}
target="_blank"
>
<span className="mr-1">Go to my Slash</span>
<Icon.ExternalLink className="w-4 h-auto" />
</a>
</div>
</div>
)
</>
) : (
<div className="w-full flex flex-col justify-start items-center">
<p>No domain and access token found.</p>

View File

@ -236,3 +236,51 @@ export declare class GetShortcutResponse extends Message<GetShortcutResponse> {
static equals(a: GetShortcutResponse | PlainMessage<GetShortcutResponse> | undefined, b: GetShortcutResponse | PlainMessage<GetShortcutResponse> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.CreateShortcutRequest
*/
export declare class CreateShortcutRequest extends Message<CreateShortcutRequest> {
/**
* @generated from field: slash.api.v2.Shortcut shortcut = 1;
*/
shortcut?: Shortcut;
constructor(data?: PartialMessage<CreateShortcutRequest>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.api.v2.CreateShortcutRequest";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateShortcutRequest;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateShortcutRequest;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateShortcutRequest;
static equals(a: CreateShortcutRequest | PlainMessage<CreateShortcutRequest> | undefined, b: CreateShortcutRequest | PlainMessage<CreateShortcutRequest> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.CreateShortcutResponse
*/
export declare class CreateShortcutResponse extends Message<CreateShortcutResponse> {
/**
* @generated from field: slash.api.v2.Shortcut shortcut = 1;
*/
shortcut?: Shortcut;
constructor(data?: PartialMessage<CreateShortcutResponse>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.api.v2.CreateShortcutResponse";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateShortcutResponse;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateShortcutResponse;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateShortcutResponse;
static equals(a: CreateShortcutResponse | PlainMessage<CreateShortcutResponse> | undefined, b: CreateShortcutResponse | PlainMessage<CreateShortcutResponse> | undefined): boolean;
}

View File

@ -90,3 +90,23 @@ export const GetShortcutResponse = proto3.makeMessageType(
],
);
/**
* @generated from message slash.api.v2.CreateShortcutRequest
*/
export const CreateShortcutRequest = proto3.makeMessageType(
"slash.api.v2.CreateShortcutRequest",
() => [
{ no: 1, name: "shortcut", kind: "message", T: Shortcut },
],
);
/**
* @generated from message slash.api.v2.CreateShortcutResponse
*/
export const CreateShortcutResponse = proto3.makeMessageType(
"slash.api.v2.CreateShortcutResponse",
() => [
{ no: 1, name: "shortcut", kind: "message", T: Shortcut },
],
);

View File

@ -66,6 +66,11 @@ export declare class User extends Message<User> {
*/
nickname: string;
/**
* @generated from field: string password = 9;
*/
password: string;
constructor(data?: PartialMessage<User>);
static readonly runtime: typeof proto3;
@ -129,6 +134,54 @@ export declare class GetUserResponse extends Message<GetUserResponse> {
static equals(a: GetUserResponse | PlainMessage<GetUserResponse> | undefined, b: GetUserResponse | PlainMessage<GetUserResponse> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.CreateUserRequest
*/
export declare class CreateUserRequest extends Message<CreateUserRequest> {
/**
* @generated from field: slash.api.v2.User user = 1;
*/
user?: User;
constructor(data?: PartialMessage<CreateUserRequest>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.api.v2.CreateUserRequest";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateUserRequest;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateUserRequest;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateUserRequest;
static equals(a: CreateUserRequest | PlainMessage<CreateUserRequest> | undefined, b: CreateUserRequest | PlainMessage<CreateUserRequest> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.CreateUserResponse
*/
export declare class CreateUserResponse extends Message<CreateUserResponse> {
/**
* @generated from field: slash.api.v2.User user = 1;
*/
user?: User;
constructor(data?: PartialMessage<CreateUserResponse>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.api.v2.CreateUserResponse";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateUserResponse;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateUserResponse;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateUserResponse;
static equals(a: CreateUserResponse | PlainMessage<CreateUserResponse> | undefined, b: CreateUserResponse | PlainMessage<CreateUserResponse> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.ListUserAccessTokensRequest
*/

View File

@ -31,6 +31,7 @@ export const User = proto3.makeMessageType(
{ no: 6, name: "role", kind: "enum", T: proto3.getEnumType(Role) },
{ no: 7, name: "email", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 8, name: "nickname", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 9, name: "password", kind: "scalar", T: 9 /* ScalarType.STRING */ },
],
);
@ -54,6 +55,26 @@ export const GetUserResponse = proto3.makeMessageType(
],
);
/**
* @generated from message slash.api.v2.CreateUserRequest
*/
export const CreateUserRequest = proto3.makeMessageType(
"slash.api.v2.CreateUserRequest",
() => [
{ no: 1, name: "user", kind: "message", T: User },
],
);
/**
* @generated from message slash.api.v2.CreateUserResponse
*/
export const CreateUserResponse = proto3.makeMessageType(
"slash.api.v2.CreateUserResponse",
() => [
{ no: 1, name: "user", kind: "message", T: User },
],
);
/**
* @generated from message slash.api.v2.ListUserAccessTokensRequest
*/

View File

@ -0,0 +1,32 @@
// @generated by protoc-gen-es v1.3.0
// @generated from file store/activity.proto (package slash.store, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3 } from "@bufbuild/protobuf";
/**
* @generated from message slash.store.ActivityShorcutCreatePayload
*/
export declare class ActivityShorcutCreatePayload extends Message<ActivityShorcutCreatePayload> {
/**
* @generated from field: int32 shortcut_id = 1;
*/
shortcutId: number;
constructor(data?: PartialMessage<ActivityShorcutCreatePayload>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.store.ActivityShorcutCreatePayload";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ActivityShorcutCreatePayload;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ActivityShorcutCreatePayload;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ActivityShorcutCreatePayload;
static equals(a: ActivityShorcutCreatePayload | PlainMessage<ActivityShorcutCreatePayload> | undefined, b: ActivityShorcutCreatePayload | PlainMessage<ActivityShorcutCreatePayload> | undefined): boolean;
}

View File

@ -0,0 +1,17 @@
// @generated by protoc-gen-es v1.3.0
// @generated from file store/activity.proto (package slash.store, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { proto3 } from "@bufbuild/protobuf";
/**
* @generated from message slash.store.ActivityShorcutCreatePayload
*/
export const ActivityShorcutCreatePayload = proto3.makeMessageType(
"slash.store.ActivityShorcutCreatePayload",
() => [
{ no: 1, name: "shortcut_id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
],
);

1
go.mod
View File

@ -70,6 +70,7 @@ require (
require (
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2
github.com/h2non/filetype v1.1.3
github.com/mssola/useragent v1.0.0
github.com/pkg/errors v0.9.1
go.deanishe.net/favicon v0.1.0

2
go.sum
View File

@ -171,6 +171,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 h1:dygLcbEBA+t/P7ck6a8AkXv6juQ4cK0RHBoh32jxhHM=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2/go.mod h1:Ap9RLCIJVtgQg1/BBgVEfypOAySvvlcpcVQkSzJCH4Y=
github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=

View File

@ -9,6 +9,7 @@ import "google/api/client.proto";
option go_package = "gen/api/v2";
service ShortcutService {
// ListShortcuts returns a list of shortcuts.
rpc ListShortcuts(ListShortcutsRequest) returns (ListShortcutsResponse) {
option (google.api.http) = {get: "/api/v2/shortcuts"};
}
@ -17,6 +18,13 @@ service ShortcutService {
option (google.api.http) = {get: "/api/v2/shortcuts/{name}"};
option (google.api.method_signature) = "name";
}
// CreateShortcut creates a shortcut.
rpc CreateShortcut(CreateShortcutRequest) returns (CreateShortcutResponse) {
option (google.api.http) = {
post: "/api/v2/shortcuts"
body: "shortcut"
};
}
}
message Shortcut {
@ -76,3 +84,11 @@ message GetShortcutRequest {
message GetShortcutResponse {
Shortcut shortcut = 1;
}
message CreateShortcutRequest {
Shortcut shortcut = 1;
}
message CreateShortcutResponse {
Shortcut shortcut = 1;
}

View File

@ -15,6 +15,13 @@ service UserService {
option (google.api.http) = {get: "/api/v2/users/{id}"};
option (google.api.method_signature) = "id";
}
// CreateUser creates a new user.
rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) {
option (google.api.http) = {
post: "/api/v2/users"
body: "user"
};
}
// ListUserAccessTokens returns a list of access tokens for a user.
rpc ListUserAccessTokens(ListUserAccessTokensRequest) returns (ListUserAccessTokensResponse) {
option (google.api.http) = {get: "/api/v2/users/{id}/access_tokens"};
@ -49,6 +56,8 @@ message User {
string email = 7;
string nickname = 8;
string password = 9;
}
enum Role {
@ -67,6 +76,14 @@ message GetUserResponse {
User user = 1;
}
message CreateUserRequest {
User user = 1;
}
message CreateUserResponse {
User user = 1;
}
message ListUserAccessTokensRequest {
// id is the user id.
int32 id = 1;

View File

@ -7,6 +7,8 @@
- [RowStatus](#slash-api-v2-RowStatus)
- [api/v2/shortcut_service.proto](#api_v2_shortcut_service-proto)
- [CreateShortcutRequest](#slash-api-v2-CreateShortcutRequest)
- [CreateShortcutResponse](#slash-api-v2-CreateShortcutResponse)
- [GetShortcutRequest](#slash-api-v2-GetShortcutRequest)
- [GetShortcutResponse](#slash-api-v2-GetShortcutResponse)
- [ListShortcutsRequest](#slash-api-v2-ListShortcutsRequest)
@ -21,6 +23,8 @@
- [api/v2/user_service.proto](#api_v2_user_service-proto)
- [CreateUserAccessTokenRequest](#slash-api-v2-CreateUserAccessTokenRequest)
- [CreateUserAccessTokenResponse](#slash-api-v2-CreateUserAccessTokenResponse)
- [CreateUserRequest](#slash-api-v2-CreateUserRequest)
- [CreateUserResponse](#slash-api-v2-CreateUserResponse)
- [DeleteUserAccessTokenRequest](#slash-api-v2-DeleteUserAccessTokenRequest)
- [DeleteUserAccessTokenResponse](#slash-api-v2-DeleteUserAccessTokenResponse)
- [GetUserRequest](#slash-api-v2-GetUserRequest)
@ -74,6 +78,36 @@
<a name="slash-api-v2-CreateShortcutRequest"></a>
### CreateShortcutRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| shortcut | [Shortcut](#slash-api-v2-Shortcut) | | |
<a name="slash-api-v2-CreateShortcutResponse"></a>
### CreateShortcutResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| shortcut | [Shortcut](#slash-api-v2-Shortcut) | | |
<a name="slash-api-v2-GetShortcutRequest"></a>
### GetShortcutRequest
@ -199,8 +233,9 @@
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| ListShortcuts | [ListShortcutsRequest](#slash-api-v2-ListShortcutsRequest) | [ListShortcutsResponse](#slash-api-v2-ListShortcutsResponse) | |
| ListShortcuts | [ListShortcutsRequest](#slash-api-v2-ListShortcutsRequest) | [ListShortcutsResponse](#slash-api-v2-ListShortcutsResponse) | ListShortcuts returns a list of shortcuts. |
| GetShortcut | [GetShortcutRequest](#slash-api-v2-GetShortcutRequest) | [GetShortcutResponse](#slash-api-v2-GetShortcutResponse) | GetShortcut returns a shortcut by name. |
| CreateShortcut | [CreateShortcutRequest](#slash-api-v2-CreateShortcutRequest) | [CreateShortcutResponse](#slash-api-v2-CreateShortcutResponse) | CreateShortcut creates a shortcut. |
@ -244,6 +279,36 @@
<a name="slash-api-v2-CreateUserRequest"></a>
### CreateUserRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| user | [User](#slash-api-v2-User) | | |
<a name="slash-api-v2-CreateUserResponse"></a>
### CreateUserResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| user | [User](#slash-api-v2-User) | | |
<a name="slash-api-v2-DeleteUserAccessTokenRequest"></a>
### DeleteUserAccessTokenRequest
@ -345,6 +410,7 @@
| role | [Role](#slash-api-v2-Role) | | |
| email | [string](#string) | | |
| nickname | [string](#string) | | |
| password | [string](#string) | | |
@ -396,6 +462,7 @@
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| GetUser | [GetUserRequest](#slash-api-v2-GetUserRequest) | [GetUserResponse](#slash-api-v2-GetUserResponse) | GetUser returns a user by id. |
| CreateUser | [CreateUserRequest](#slash-api-v2-CreateUserRequest) | [CreateUserResponse](#slash-api-v2-CreateUserResponse) | CreateUser creates a new user. |
| ListUserAccessTokens | [ListUserAccessTokensRequest](#slash-api-v2-ListUserAccessTokensRequest) | [ListUserAccessTokensResponse](#slash-api-v2-ListUserAccessTokensResponse) | ListUserAccessTokens returns a list of access tokens for a user. |
| CreateUserAccessToken | [CreateUserAccessTokenRequest](#slash-api-v2-CreateUserAccessTokenRequest) | [CreateUserAccessTokenResponse](#slash-api-v2-CreateUserAccessTokenResponse) | CreateUserAccessToken creates a new access token for a user. |
| DeleteUserAccessToken | [DeleteUserAccessTokenRequest](#slash-api-v2-DeleteUserAccessTokenRequest) | [DeleteUserAccessTokenResponse](#slash-api-v2-DeleteUserAccessTokenResponse) | DeleteUserAccessToken deletes an access token for a user. |

View File

@ -450,6 +450,100 @@ func (x *GetShortcutResponse) GetShortcut() *Shortcut {
return nil
}
type CreateShortcutRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Shortcut *Shortcut `protobuf:"bytes,1,opt,name=shortcut,proto3" json:"shortcut,omitempty"`
}
func (x *CreateShortcutRequest) Reset() {
*x = CreateShortcutRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_shortcut_service_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateShortcutRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateShortcutRequest) ProtoMessage() {}
func (x *CreateShortcutRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_shortcut_service_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateShortcutRequest.ProtoReflect.Descriptor instead.
func (*CreateShortcutRequest) Descriptor() ([]byte, []int) {
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{6}
}
func (x *CreateShortcutRequest) GetShortcut() *Shortcut {
if x != nil {
return x.Shortcut
}
return nil
}
type CreateShortcutResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Shortcut *Shortcut `protobuf:"bytes,1,opt,name=shortcut,proto3" json:"shortcut,omitempty"`
}
func (x *CreateShortcutResponse) Reset() {
*x = CreateShortcutResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_shortcut_service_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateShortcutResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateShortcutResponse) ProtoMessage() {}
func (x *CreateShortcutResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_shortcut_service_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateShortcutResponse.ProtoReflect.Descriptor instead.
func (*CreateShortcutResponse) Descriptor() ([]byte, []int) {
return file_api_v2_shortcut_service_proto_rawDescGZIP(), []int{7}
}
func (x *CreateShortcutResponse) GetShortcut() *Shortcut {
if x != nil {
return x.Shortcut
}
return nil
}
var File_api_v2_shortcut_service_proto protoreflect.FileDescriptor
var file_api_v2_shortcut_service_proto_rawDesc = []byte{
@ -506,40 +600,58 @@ var file_api_v2_shortcut_service_proto_rawDesc = []byte{
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63,
0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74,
0x52, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x2a, 0x50, 0x0a, 0x0a, 0x56, 0x69,
0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x49, 0x53, 0x49,
0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10,
0x01, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x10, 0x02,
0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x03, 0x32, 0x83, 0x02, 0x0a,
0x0f, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x12, 0x73, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74,
0x73, 0x12, 0x22, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75,
0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x68, 0x6f, 0x72,
0x74, 0x63, 0x75, 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72,
0x74, 0x63, 0x75, 0x74, 0x12, 0x20, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0xda, 0x41, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76,
0x32, 0x2f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d,
0x65, 0x7d, 0x42, 0xab, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x14, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75,
0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,
0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a,
0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32,
0xa2, 0x02, 0x03, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41,
0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70,
0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69,
0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
0x02, 0x0e, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x52, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x22, 0x4b, 0x0a, 0x15, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x08, 0x73,
0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x22, 0x4c, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x32, 0x0a, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x32, 0x2e, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x08, 0x73, 0x68, 0x6f,
0x72, 0x74, 0x63, 0x75, 0x74, 0x2a, 0x50, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c,
0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54,
0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
0x0b, 0x0a, 0x07, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09,
0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50,
0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x03, 0x32, 0x86, 0x03, 0x0a, 0x0f, 0x53, 0x68, 0x6f, 0x72,
0x74, 0x63, 0x75, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x0d, 0x4c,
0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x73,
0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x23, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73,
0x12, 0x7b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x12,
0x20, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47,
0x65, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x21, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
0x2e, 0x47, 0x65, 0x74, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x68, 0x6f,
0x72, 0x74, 0x63, 0x75, 0x74, 0x73, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x80, 0x01,
0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74,
0x12, 0x23, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x6f, 0x72, 0x74,
0x63, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x1d, 0x3a, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x22, 0x11, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x73,
0x42, 0xab, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x14, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63,
0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65,
0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02,
0x03, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41, 0x70, 0x69,
0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c,
0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56,
0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e,
0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -555,32 +667,38 @@ func file_api_v2_shortcut_service_proto_rawDescGZIP() []byte {
}
var file_api_v2_shortcut_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_api_v2_shortcut_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_api_v2_shortcut_service_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
var file_api_v2_shortcut_service_proto_goTypes = []interface{}{
(Visibility)(0), // 0: slash.api.v2.Visibility
(*Shortcut)(nil), // 1: slash.api.v2.Shortcut
(*OpenGraphMetadata)(nil), // 2: slash.api.v2.OpenGraphMetadata
(*ListShortcutsRequest)(nil), // 3: slash.api.v2.ListShortcutsRequest
(*ListShortcutsResponse)(nil), // 4: slash.api.v2.ListShortcutsResponse
(*GetShortcutRequest)(nil), // 5: slash.api.v2.GetShortcutRequest
(*GetShortcutResponse)(nil), // 6: slash.api.v2.GetShortcutResponse
(RowStatus)(0), // 7: slash.api.v2.RowStatus
(Visibility)(0), // 0: slash.api.v2.Visibility
(*Shortcut)(nil), // 1: slash.api.v2.Shortcut
(*OpenGraphMetadata)(nil), // 2: slash.api.v2.OpenGraphMetadata
(*ListShortcutsRequest)(nil), // 3: slash.api.v2.ListShortcutsRequest
(*ListShortcutsResponse)(nil), // 4: slash.api.v2.ListShortcutsResponse
(*GetShortcutRequest)(nil), // 5: slash.api.v2.GetShortcutRequest
(*GetShortcutResponse)(nil), // 6: slash.api.v2.GetShortcutResponse
(*CreateShortcutRequest)(nil), // 7: slash.api.v2.CreateShortcutRequest
(*CreateShortcutResponse)(nil), // 8: slash.api.v2.CreateShortcutResponse
(RowStatus)(0), // 9: slash.api.v2.RowStatus
}
var file_api_v2_shortcut_service_proto_depIdxs = []int32{
7, // 0: slash.api.v2.Shortcut.row_status:type_name -> slash.api.v2.RowStatus
0, // 1: slash.api.v2.Shortcut.visibility:type_name -> slash.api.v2.Visibility
2, // 2: slash.api.v2.Shortcut.og_metadata:type_name -> slash.api.v2.OpenGraphMetadata
1, // 3: slash.api.v2.ListShortcutsResponse.shortcuts:type_name -> slash.api.v2.Shortcut
1, // 4: slash.api.v2.GetShortcutResponse.shortcut:type_name -> slash.api.v2.Shortcut
3, // 5: slash.api.v2.ShortcutService.ListShortcuts:input_type -> slash.api.v2.ListShortcutsRequest
5, // 6: slash.api.v2.ShortcutService.GetShortcut:input_type -> slash.api.v2.GetShortcutRequest
4, // 7: slash.api.v2.ShortcutService.ListShortcuts:output_type -> slash.api.v2.ListShortcutsResponse
6, // 8: slash.api.v2.ShortcutService.GetShortcut:output_type -> slash.api.v2.GetShortcutResponse
7, // [7:9] is the sub-list for method output_type
5, // [5:7] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
9, // 0: slash.api.v2.Shortcut.row_status:type_name -> slash.api.v2.RowStatus
0, // 1: slash.api.v2.Shortcut.visibility:type_name -> slash.api.v2.Visibility
2, // 2: slash.api.v2.Shortcut.og_metadata:type_name -> slash.api.v2.OpenGraphMetadata
1, // 3: slash.api.v2.ListShortcutsResponse.shortcuts:type_name -> slash.api.v2.Shortcut
1, // 4: slash.api.v2.GetShortcutResponse.shortcut:type_name -> slash.api.v2.Shortcut
1, // 5: slash.api.v2.CreateShortcutRequest.shortcut:type_name -> slash.api.v2.Shortcut
1, // 6: slash.api.v2.CreateShortcutResponse.shortcut:type_name -> slash.api.v2.Shortcut
3, // 7: slash.api.v2.ShortcutService.ListShortcuts:input_type -> slash.api.v2.ListShortcutsRequest
5, // 8: slash.api.v2.ShortcutService.GetShortcut:input_type -> slash.api.v2.GetShortcutRequest
7, // 9: slash.api.v2.ShortcutService.CreateShortcut:input_type -> slash.api.v2.CreateShortcutRequest
4, // 10: slash.api.v2.ShortcutService.ListShortcuts:output_type -> slash.api.v2.ListShortcutsResponse
6, // 11: slash.api.v2.ShortcutService.GetShortcut:output_type -> slash.api.v2.GetShortcutResponse
8, // 12: slash.api.v2.ShortcutService.CreateShortcut:output_type -> slash.api.v2.CreateShortcutResponse
10, // [10:13] is the sub-list for method output_type
7, // [7:10] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
}
func init() { file_api_v2_shortcut_service_proto_init() }
@ -662,6 +780,30 @@ func file_api_v2_shortcut_service_proto_init() {
return nil
}
}
file_api_v2_shortcut_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateShortcutRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_v2_shortcut_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateShortcutResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@ -669,7 +811,7 @@ func file_api_v2_shortcut_service_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_v2_shortcut_service_proto_rawDesc,
NumEnums: 1,
NumMessages: 6,
NumMessages: 8,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -101,6 +101,40 @@ func local_request_ShortcutService_GetShortcut_0(ctx context.Context, marshaler
}
func request_ShortcutService_CreateShortcut_0(ctx context.Context, marshaler runtime.Marshaler, client ShortcutServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CreateShortcutRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Shortcut); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.CreateShortcut(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ShortcutService_CreateShortcut_0(ctx context.Context, marshaler runtime.Marshaler, server ShortcutServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CreateShortcutRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Shortcut); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.CreateShortcut(ctx, &protoReq)
return msg, metadata, err
}
// RegisterShortcutServiceHandlerServer registers the http handlers for service ShortcutService to "mux".
// UnaryRPC :call ShortcutServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@ -157,6 +191,31 @@ func RegisterShortcutServiceHandlerServer(ctx context.Context, mux *runtime.Serv
})
mux.Handle("POST", pattern_ShortcutService_CreateShortcut_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/slash.api.v2.ShortcutService/CreateShortcut", runtime.WithHTTPPathPattern("/api/v2/shortcuts"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ShortcutService_CreateShortcut_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ShortcutService_CreateShortcut_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@ -242,6 +301,28 @@ func RegisterShortcutServiceHandlerClient(ctx context.Context, mux *runtime.Serv
})
mux.Handle("POST", pattern_ShortcutService_CreateShortcut_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/slash.api.v2.ShortcutService/CreateShortcut", runtime.WithHTTPPathPattern("/api/v2/shortcuts"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ShortcutService_CreateShortcut_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ShortcutService_CreateShortcut_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@ -249,10 +330,14 @@ var (
pattern_ShortcutService_ListShortcuts_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "shortcuts"}, ""))
pattern_ShortcutService_GetShortcut_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "shortcuts", "name"}, ""))
pattern_ShortcutService_CreateShortcut_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "shortcuts"}, ""))
)
var (
forward_ShortcutService_ListShortcuts_0 = runtime.ForwardResponseMessage
forward_ShortcutService_GetShortcut_0 = runtime.ForwardResponseMessage
forward_ShortcutService_CreateShortcut_0 = runtime.ForwardResponseMessage
)

View File

@ -19,17 +19,21 @@ import (
const _ = grpc.SupportPackageIsVersion7
const (
ShortcutService_ListShortcuts_FullMethodName = "/slash.api.v2.ShortcutService/ListShortcuts"
ShortcutService_GetShortcut_FullMethodName = "/slash.api.v2.ShortcutService/GetShortcut"
ShortcutService_ListShortcuts_FullMethodName = "/slash.api.v2.ShortcutService/ListShortcuts"
ShortcutService_GetShortcut_FullMethodName = "/slash.api.v2.ShortcutService/GetShortcut"
ShortcutService_CreateShortcut_FullMethodName = "/slash.api.v2.ShortcutService/CreateShortcut"
)
// ShortcutServiceClient is the client API for ShortcutService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ShortcutServiceClient interface {
// ListShortcuts returns a list of shortcuts.
ListShortcuts(ctx context.Context, in *ListShortcutsRequest, opts ...grpc.CallOption) (*ListShortcutsResponse, error)
// GetShortcut returns a shortcut by name.
GetShortcut(ctx context.Context, in *GetShortcutRequest, opts ...grpc.CallOption) (*GetShortcutResponse, error)
// CreateShortcut creates a shortcut.
CreateShortcut(ctx context.Context, in *CreateShortcutRequest, opts ...grpc.CallOption) (*CreateShortcutResponse, error)
}
type shortcutServiceClient struct {
@ -58,13 +62,25 @@ func (c *shortcutServiceClient) GetShortcut(ctx context.Context, in *GetShortcut
return out, nil
}
func (c *shortcutServiceClient) CreateShortcut(ctx context.Context, in *CreateShortcutRequest, opts ...grpc.CallOption) (*CreateShortcutResponse, error) {
out := new(CreateShortcutResponse)
err := c.cc.Invoke(ctx, ShortcutService_CreateShortcut_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ShortcutServiceServer is the server API for ShortcutService service.
// All implementations must embed UnimplementedShortcutServiceServer
// for forward compatibility
type ShortcutServiceServer interface {
// ListShortcuts returns a list of shortcuts.
ListShortcuts(context.Context, *ListShortcutsRequest) (*ListShortcutsResponse, error)
// GetShortcut returns a shortcut by name.
GetShortcut(context.Context, *GetShortcutRequest) (*GetShortcutResponse, error)
// CreateShortcut creates a shortcut.
CreateShortcut(context.Context, *CreateShortcutRequest) (*CreateShortcutResponse, error)
mustEmbedUnimplementedShortcutServiceServer()
}
@ -78,6 +94,9 @@ func (UnimplementedShortcutServiceServer) ListShortcuts(context.Context, *ListSh
func (UnimplementedShortcutServiceServer) GetShortcut(context.Context, *GetShortcutRequest) (*GetShortcutResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetShortcut not implemented")
}
func (UnimplementedShortcutServiceServer) CreateShortcut(context.Context, *CreateShortcutRequest) (*CreateShortcutResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateShortcut not implemented")
}
func (UnimplementedShortcutServiceServer) mustEmbedUnimplementedShortcutServiceServer() {}
// UnsafeShortcutServiceServer may be embedded to opt out of forward compatibility for this service.
@ -127,6 +146,24 @@ func _ShortcutService_GetShortcut_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler)
}
func _ShortcutService_CreateShortcut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateShortcutRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ShortcutServiceServer).CreateShortcut(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ShortcutService_CreateShortcut_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ShortcutServiceServer).CreateShortcut(ctx, req.(*CreateShortcutRequest))
}
return interceptor(ctx, in, info, handler)
}
// ShortcutService_ServiceDesc is the grpc.ServiceDesc for ShortcutService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -142,6 +179,10 @@ var ShortcutService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetShortcut",
Handler: _ShortcutService_GetShortcut_Handler,
},
{
MethodName: "CreateShortcut",
Handler: _ShortcutService_CreateShortcut_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/v2/shortcut_service.proto",

View File

@ -83,6 +83,7 @@ type User struct {
Role Role `protobuf:"varint,6,opt,name=role,proto3,enum=slash.api.v2.Role" json:"role,omitempty"`
Email string `protobuf:"bytes,7,opt,name=email,proto3" json:"email,omitempty"`
Nickname string `protobuf:"bytes,8,opt,name=nickname,proto3" json:"nickname,omitempty"`
Password string `protobuf:"bytes,9,opt,name=password,proto3" json:"password,omitempty"`
}
func (x *User) Reset() {
@ -166,6 +167,13 @@ func (x *User) GetNickname() string {
return ""
}
func (x *User) GetPassword() string {
if x != nil {
return x.Password
}
return ""
}
type GetUserRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -260,6 +268,100 @@ func (x *GetUserResponse) GetUser() *User {
return nil
}
type CreateUserRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
}
func (x *CreateUserRequest) Reset() {
*x = CreateUserRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateUserRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateUserRequest) ProtoMessage() {}
func (x *CreateUserRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateUserRequest.ProtoReflect.Descriptor instead.
func (*CreateUserRequest) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{3}
}
func (x *CreateUserRequest) GetUser() *User {
if x != nil {
return x.User
}
return nil
}
type CreateUserResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
}
func (x *CreateUserResponse) Reset() {
*x = CreateUserResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateUserResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateUserResponse) ProtoMessage() {}
func (x *CreateUserResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateUserResponse.ProtoReflect.Descriptor instead.
func (*CreateUserResponse) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{4}
}
func (x *CreateUserResponse) GetUser() *User {
if x != nil {
return x.User
}
return nil
}
type ListUserAccessTokensRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -272,7 +374,7 @@ type ListUserAccessTokensRequest struct {
func (x *ListUserAccessTokensRequest) Reset() {
*x = ListUserAccessTokensRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[3]
mi := &file_api_v2_user_service_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -285,7 +387,7 @@ func (x *ListUserAccessTokensRequest) String() string {
func (*ListUserAccessTokensRequest) ProtoMessage() {}
func (x *ListUserAccessTokensRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[3]
mi := &file_api_v2_user_service_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -298,7 +400,7 @@ func (x *ListUserAccessTokensRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListUserAccessTokensRequest.ProtoReflect.Descriptor instead.
func (*ListUserAccessTokensRequest) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{3}
return file_api_v2_user_service_proto_rawDescGZIP(), []int{5}
}
func (x *ListUserAccessTokensRequest) GetId() int32 {
@ -319,7 +421,7 @@ type ListUserAccessTokensResponse struct {
func (x *ListUserAccessTokensResponse) Reset() {
*x = ListUserAccessTokensResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[4]
mi := &file_api_v2_user_service_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -332,7 +434,7 @@ func (x *ListUserAccessTokensResponse) String() string {
func (*ListUserAccessTokensResponse) ProtoMessage() {}
func (x *ListUserAccessTokensResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[4]
mi := &file_api_v2_user_service_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -345,7 +447,7 @@ func (x *ListUserAccessTokensResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListUserAccessTokensResponse.ProtoReflect.Descriptor instead.
func (*ListUserAccessTokensResponse) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{4}
return file_api_v2_user_service_proto_rawDescGZIP(), []int{6}
}
func (x *ListUserAccessTokensResponse) GetAccessTokens() []*UserAccessToken {
@ -368,7 +470,7 @@ type CreateUserAccessTokenRequest struct {
func (x *CreateUserAccessTokenRequest) Reset() {
*x = CreateUserAccessTokenRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[5]
mi := &file_api_v2_user_service_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -381,7 +483,7 @@ func (x *CreateUserAccessTokenRequest) String() string {
func (*CreateUserAccessTokenRequest) ProtoMessage() {}
func (x *CreateUserAccessTokenRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[5]
mi := &file_api_v2_user_service_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -394,7 +496,7 @@ func (x *CreateUserAccessTokenRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CreateUserAccessTokenRequest.ProtoReflect.Descriptor instead.
func (*CreateUserAccessTokenRequest) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{5}
return file_api_v2_user_service_proto_rawDescGZIP(), []int{7}
}
func (x *CreateUserAccessTokenRequest) GetId() int32 {
@ -422,7 +524,7 @@ type CreateUserAccessTokenResponse struct {
func (x *CreateUserAccessTokenResponse) Reset() {
*x = CreateUserAccessTokenResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[6]
mi := &file_api_v2_user_service_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -435,7 +537,7 @@ func (x *CreateUserAccessTokenResponse) String() string {
func (*CreateUserAccessTokenResponse) ProtoMessage() {}
func (x *CreateUserAccessTokenResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[6]
mi := &file_api_v2_user_service_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -448,7 +550,7 @@ func (x *CreateUserAccessTokenResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use CreateUserAccessTokenResponse.ProtoReflect.Descriptor instead.
func (*CreateUserAccessTokenResponse) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{6}
return file_api_v2_user_service_proto_rawDescGZIP(), []int{8}
}
func (x *CreateUserAccessTokenResponse) GetAccessToken() *UserAccessToken {
@ -472,7 +574,7 @@ type DeleteUserAccessTokenRequest struct {
func (x *DeleteUserAccessTokenRequest) Reset() {
*x = DeleteUserAccessTokenRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[7]
mi := &file_api_v2_user_service_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -485,7 +587,7 @@ func (x *DeleteUserAccessTokenRequest) String() string {
func (*DeleteUserAccessTokenRequest) ProtoMessage() {}
func (x *DeleteUserAccessTokenRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[7]
mi := &file_api_v2_user_service_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -498,7 +600,7 @@ func (x *DeleteUserAccessTokenRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeleteUserAccessTokenRequest.ProtoReflect.Descriptor instead.
func (*DeleteUserAccessTokenRequest) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{7}
return file_api_v2_user_service_proto_rawDescGZIP(), []int{9}
}
func (x *DeleteUserAccessTokenRequest) GetId() int32 {
@ -524,7 +626,7 @@ type DeleteUserAccessTokenResponse struct {
func (x *DeleteUserAccessTokenResponse) Reset() {
*x = DeleteUserAccessTokenResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[8]
mi := &file_api_v2_user_service_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -537,7 +639,7 @@ func (x *DeleteUserAccessTokenResponse) String() string {
func (*DeleteUserAccessTokenResponse) ProtoMessage() {}
func (x *DeleteUserAccessTokenResponse) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[8]
mi := &file_api_v2_user_service_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -550,7 +652,7 @@ func (x *DeleteUserAccessTokenResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeleteUserAccessTokenResponse.ProtoReflect.Descriptor instead.
func (*DeleteUserAccessTokenResponse) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{8}
return file_api_v2_user_service_proto_rawDescGZIP(), []int{10}
}
type UserAccessToken struct {
@ -567,7 +669,7 @@ type UserAccessToken struct {
func (x *UserAccessToken) Reset() {
*x = UserAccessToken{}
if protoimpl.UnsafeEnabled {
mi := &file_api_v2_user_service_proto_msgTypes[9]
mi := &file_api_v2_user_service_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -580,7 +682,7 @@ func (x *UserAccessToken) String() string {
func (*UserAccessToken) ProtoMessage() {}
func (x *UserAccessToken) ProtoReflect() protoreflect.Message {
mi := &file_api_v2_user_service_proto_msgTypes[9]
mi := &file_api_v2_user_service_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -593,7 +695,7 @@ func (x *UserAccessToken) ProtoReflect() protoreflect.Message {
// Deprecated: Use UserAccessToken.ProtoReflect.Descriptor instead.
func (*UserAccessToken) Descriptor() ([]byte, []int) {
return file_api_v2_user_service_proto_rawDescGZIP(), []int{9}
return file_api_v2_user_service_proto_rawDescGZIP(), []int{11}
}
func (x *UserAccessToken) GetAccessToken() string {
@ -636,7 +738,7 @@ var file_api_v2_user_service_proto_rawDesc = []byte{
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 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, 0xe6, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12,
0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
@ -650,111 +752,128 @@ var file_api_v2_user_service_proto_rawDesc = []byte{
0x76, 0x32, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a,
0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d,
0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x22,
0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69,
0x64, 0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2d, 0x0a, 0x1b,
0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x62, 0x0a, 0x1c, 0x4c,
0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x61,
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22,
0x79, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63,
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12,
0x49, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6c, 0x61,
0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63,
0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x41,
0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x61, 0x0a, 0x1d, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x61,
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28,
0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x0a, 0x0e, 0x47,
0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a,
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x39, 0x0a,
0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12,
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73,
0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x3b, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a,
0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6c,
0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52,
0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x3c, 0x0a, 0x12, 0x43, 0x72, 0x65, 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, 0x73, 0x6c, 0x61, 0x73,
0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75,
0x73, 0x65, 0x72, 0x22, 0x2d, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41,
0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02,
0x69, 0x64, 0x22, 0x62, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63,
0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6c, 0x61, 0x73,
0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63,
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x79, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x49, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61,
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x51, 0x0a,
0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73,
0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a,
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a,
0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63,
0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0xca, 0x01, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63,
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x09, 0x69, 0x73,
0x73, 0x75, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x69, 0x73, 0x73, 0x75, 0x65,
0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61,
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x2a, 0x31,
0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55,
0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05,
0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10,
0x02, 0x32, 0x88, 0x05, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x12, 0x67, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x73,
0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55,
0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x6c, 0x61,
0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xda, 0x41, 0x02, 0x69, 0x64,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f,
0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9c, 0x01, 0x0a, 0x14, 0x4c,
0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x52, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x22, 0x61, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41,
0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65,
0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x51, 0x0a, 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73,
0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65,
0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xca, 0x01, 0x0a, 0x0f, 0x55, 0x73, 0x65,
0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c,
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12,
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x37, 0x0a, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
0x52, 0x08, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78,
0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69,
0x72, 0x65, 0x73, 0x41, 0x74, 0x2a, 0x31, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a,
0x10, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x08,
0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x02, 0x32, 0xf6, 0x05, 0x0a, 0x0b, 0x55, 0x73, 0x65,
0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x67, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55,
0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x1f, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64,
0x7d, 0x12, 0x6c, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12,
0x1f, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x20, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x04, 0x75, 0x73, 0x65, 0x72,
0x22, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12,
0x9c, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65,
0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72,
0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73,
0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a,
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0xda, 0x41, 0x02, 0x69,
0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x63, 0x63, 0x65,
0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x15, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63,
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x2b, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0xda, 0x41,
0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x3a, 0x11, 0x75, 0x73, 0x65, 0x72, 0x5f,
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x20, 0x2f, 0x61,
0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x2d, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d,
0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xbb,
0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63,
0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xb2,
0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63,
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63,
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, 0x49, 0xda, 0x41, 0x0f, 0x69, 0x64, 0x2c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x2a, 0x2f, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f,
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x2f, 0x7b, 0x61,
0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x7d, 0x42, 0xa7, 0x01, 0x0a,
0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x32, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72,
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53,
0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c,
0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61,
0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74,
0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41,
0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x22, 0x40, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x3a, 0x11,
0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x22, 0x20, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73,
0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x73, 0x12, 0xbb, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73,
0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x2e,
0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x6c, 0x61, 0x73,
0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55,
0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x49, 0xda, 0x41, 0x0f, 0x69, 0x64, 0x2c, 0x61, 0x63,
0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31,
0x2a, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f,
0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x7d, 0x42, 0xa7, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73,
0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x53, 0x41,
0x58, 0xaa, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32,
0xca, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2,
0x02, 0x18, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47,
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x53, 0x6c, 0x61,
0x73, 0x68, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (
@ -770,44 +889,50 @@ func file_api_v2_user_service_proto_rawDescGZIP() []byte {
}
var file_api_v2_user_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_api_v2_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_api_v2_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_api_v2_user_service_proto_goTypes = []interface{}{
(Role)(0), // 0: slash.api.v2.Role
(*User)(nil), // 1: slash.api.v2.User
(*GetUserRequest)(nil), // 2: slash.api.v2.GetUserRequest
(*GetUserResponse)(nil), // 3: slash.api.v2.GetUserResponse
(*ListUserAccessTokensRequest)(nil), // 4: slash.api.v2.ListUserAccessTokensRequest
(*ListUserAccessTokensResponse)(nil), // 5: slash.api.v2.ListUserAccessTokensResponse
(*CreateUserAccessTokenRequest)(nil), // 6: slash.api.v2.CreateUserAccessTokenRequest
(*CreateUserAccessTokenResponse)(nil), // 7: slash.api.v2.CreateUserAccessTokenResponse
(*DeleteUserAccessTokenRequest)(nil), // 8: slash.api.v2.DeleteUserAccessTokenRequest
(*DeleteUserAccessTokenResponse)(nil), // 9: slash.api.v2.DeleteUserAccessTokenResponse
(*UserAccessToken)(nil), // 10: slash.api.v2.UserAccessToken
(RowStatus)(0), // 11: slash.api.v2.RowStatus
(*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp
(*CreateUserRequest)(nil), // 4: slash.api.v2.CreateUserRequest
(*CreateUserResponse)(nil), // 5: slash.api.v2.CreateUserResponse
(*ListUserAccessTokensRequest)(nil), // 6: slash.api.v2.ListUserAccessTokensRequest
(*ListUserAccessTokensResponse)(nil), // 7: slash.api.v2.ListUserAccessTokensResponse
(*CreateUserAccessTokenRequest)(nil), // 8: slash.api.v2.CreateUserAccessTokenRequest
(*CreateUserAccessTokenResponse)(nil), // 9: slash.api.v2.CreateUserAccessTokenResponse
(*DeleteUserAccessTokenRequest)(nil), // 10: slash.api.v2.DeleteUserAccessTokenRequest
(*DeleteUserAccessTokenResponse)(nil), // 11: slash.api.v2.DeleteUserAccessTokenResponse
(*UserAccessToken)(nil), // 12: slash.api.v2.UserAccessToken
(RowStatus)(0), // 13: slash.api.v2.RowStatus
(*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp
}
var file_api_v2_user_service_proto_depIdxs = []int32{
11, // 0: slash.api.v2.User.row_status:type_name -> slash.api.v2.RowStatus
13, // 0: slash.api.v2.User.row_status:type_name -> slash.api.v2.RowStatus
0, // 1: slash.api.v2.User.role:type_name -> slash.api.v2.Role
1, // 2: slash.api.v2.GetUserResponse.user:type_name -> slash.api.v2.User
10, // 3: slash.api.v2.ListUserAccessTokensResponse.access_tokens:type_name -> slash.api.v2.UserAccessToken
10, // 4: slash.api.v2.CreateUserAccessTokenRequest.user_access_token:type_name -> slash.api.v2.UserAccessToken
10, // 5: slash.api.v2.CreateUserAccessTokenResponse.access_token:type_name -> slash.api.v2.UserAccessToken
12, // 6: slash.api.v2.UserAccessToken.issued_at:type_name -> google.protobuf.Timestamp
12, // 7: slash.api.v2.UserAccessToken.expires_at:type_name -> google.protobuf.Timestamp
2, // 8: slash.api.v2.UserService.GetUser:input_type -> slash.api.v2.GetUserRequest
4, // 9: slash.api.v2.UserService.ListUserAccessTokens:input_type -> slash.api.v2.ListUserAccessTokensRequest
6, // 10: slash.api.v2.UserService.CreateUserAccessToken:input_type -> slash.api.v2.CreateUserAccessTokenRequest
8, // 11: slash.api.v2.UserService.DeleteUserAccessToken:input_type -> slash.api.v2.DeleteUserAccessTokenRequest
3, // 12: slash.api.v2.UserService.GetUser:output_type -> slash.api.v2.GetUserResponse
5, // 13: slash.api.v2.UserService.ListUserAccessTokens:output_type -> slash.api.v2.ListUserAccessTokensResponse
7, // 14: slash.api.v2.UserService.CreateUserAccessToken:output_type -> slash.api.v2.CreateUserAccessTokenResponse
9, // 15: slash.api.v2.UserService.DeleteUserAccessToken:output_type -> slash.api.v2.DeleteUserAccessTokenResponse
12, // [12:16] is the sub-list for method output_type
8, // [8:12] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
1, // 3: slash.api.v2.CreateUserRequest.user:type_name -> slash.api.v2.User
1, // 4: slash.api.v2.CreateUserResponse.user:type_name -> slash.api.v2.User
12, // 5: slash.api.v2.ListUserAccessTokensResponse.access_tokens:type_name -> slash.api.v2.UserAccessToken
12, // 6: slash.api.v2.CreateUserAccessTokenRequest.user_access_token:type_name -> slash.api.v2.UserAccessToken
12, // 7: slash.api.v2.CreateUserAccessTokenResponse.access_token:type_name -> slash.api.v2.UserAccessToken
14, // 8: slash.api.v2.UserAccessToken.issued_at:type_name -> google.protobuf.Timestamp
14, // 9: slash.api.v2.UserAccessToken.expires_at:type_name -> google.protobuf.Timestamp
2, // 10: slash.api.v2.UserService.GetUser:input_type -> slash.api.v2.GetUserRequest
4, // 11: slash.api.v2.UserService.CreateUser:input_type -> slash.api.v2.CreateUserRequest
6, // 12: slash.api.v2.UserService.ListUserAccessTokens:input_type -> slash.api.v2.ListUserAccessTokensRequest
8, // 13: slash.api.v2.UserService.CreateUserAccessToken:input_type -> slash.api.v2.CreateUserAccessTokenRequest
10, // 14: slash.api.v2.UserService.DeleteUserAccessToken:input_type -> slash.api.v2.DeleteUserAccessTokenRequest
3, // 15: slash.api.v2.UserService.GetUser:output_type -> slash.api.v2.GetUserResponse
5, // 16: slash.api.v2.UserService.CreateUser:output_type -> slash.api.v2.CreateUserResponse
7, // 17: slash.api.v2.UserService.ListUserAccessTokens:output_type -> slash.api.v2.ListUserAccessTokensResponse
9, // 18: slash.api.v2.UserService.CreateUserAccessToken:output_type -> slash.api.v2.CreateUserAccessTokenResponse
11, // 19: slash.api.v2.UserService.DeleteUserAccessToken:output_type -> slash.api.v2.DeleteUserAccessTokenResponse
15, // [15:20] is the sub-list for method output_type
10, // [10:15] is the sub-list for method input_type
10, // [10:10] is the sub-list for extension type_name
10, // [10:10] is the sub-list for extension extendee
0, // [0:10] is the sub-list for field type_name
}
func init() { file_api_v2_user_service_proto_init() }
@ -854,7 +979,7 @@ func file_api_v2_user_service_proto_init() {
}
}
file_api_v2_user_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListUserAccessTokensRequest); i {
switch v := v.(*CreateUserRequest); i {
case 0:
return &v.state
case 1:
@ -866,7 +991,7 @@ func file_api_v2_user_service_proto_init() {
}
}
file_api_v2_user_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListUserAccessTokensResponse); i {
switch v := v.(*CreateUserResponse); i {
case 0:
return &v.state
case 1:
@ -878,7 +1003,7 @@ func file_api_v2_user_service_proto_init() {
}
}
file_api_v2_user_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateUserAccessTokenRequest); i {
switch v := v.(*ListUserAccessTokensRequest); i {
case 0:
return &v.state
case 1:
@ -890,7 +1015,7 @@ func file_api_v2_user_service_proto_init() {
}
}
file_api_v2_user_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateUserAccessTokenResponse); i {
switch v := v.(*ListUserAccessTokensResponse); i {
case 0:
return &v.state
case 1:
@ -902,7 +1027,7 @@ func file_api_v2_user_service_proto_init() {
}
}
file_api_v2_user_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteUserAccessTokenRequest); i {
switch v := v.(*CreateUserAccessTokenRequest); i {
case 0:
return &v.state
case 1:
@ -914,7 +1039,7 @@ func file_api_v2_user_service_proto_init() {
}
}
file_api_v2_user_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteUserAccessTokenResponse); i {
switch v := v.(*CreateUserAccessTokenResponse); i {
case 0:
return &v.state
case 1:
@ -926,6 +1051,30 @@ func file_api_v2_user_service_proto_init() {
}
}
file_api_v2_user_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteUserAccessTokenRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_v2_user_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteUserAccessTokenResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_v2_user_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UserAccessToken); i {
case 0:
return &v.state
@ -944,7 +1093,7 @@ func file_api_v2_user_service_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_v2_user_service_proto_rawDesc,
NumEnums: 1,
NumMessages: 10,
NumMessages: 12,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -83,6 +83,40 @@ func local_request_UserService_GetUser_0(ctx context.Context, marshaler runtime.
}
func request_UserService_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CreateUserRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.User); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.CreateUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_UserService_CreateUser_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CreateUserRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.User); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.CreateUser(ctx, &protoReq)
return msg, metadata, err
}
func request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ListUserAccessTokensRequest
var metadata runtime.ServerMetadata
@ -306,6 +340,31 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("POST", pattern_UserService_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/slash.api.v2.UserService/CreateUser", runtime.WithHTTPPathPattern("/api/v2/users"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_UserService_CreateUser_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_UserService_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_UserService_ListUserAccessTokens_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@ -444,6 +503,28 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
})
mux.Handle("POST", pattern_UserService_CreateUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/slash.api.v2.UserService/CreateUser", runtime.WithHTTPPathPattern("/api/v2/users"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_UserService_CreateUser_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_UserService_CreateUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_UserService_ListUserAccessTokens_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@ -516,6 +597,8 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux
var (
pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "users", "id"}, ""))
pattern_UserService_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "users"}, ""))
pattern_UserService_ListUserAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "users", "id", "access_tokens"}, ""))
pattern_UserService_CreateUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "users", "id", "access_tokens"}, ""))
@ -526,6 +609,8 @@ var (
var (
forward_UserService_GetUser_0 = runtime.ForwardResponseMessage
forward_UserService_CreateUser_0 = runtime.ForwardResponseMessage
forward_UserService_ListUserAccessTokens_0 = runtime.ForwardResponseMessage
forward_UserService_CreateUserAccessToken_0 = runtime.ForwardResponseMessage

View File

@ -20,6 +20,7 @@ const _ = grpc.SupportPackageIsVersion7
const (
UserService_GetUser_FullMethodName = "/slash.api.v2.UserService/GetUser"
UserService_CreateUser_FullMethodName = "/slash.api.v2.UserService/CreateUser"
UserService_ListUserAccessTokens_FullMethodName = "/slash.api.v2.UserService/ListUserAccessTokens"
UserService_CreateUserAccessToken_FullMethodName = "/slash.api.v2.UserService/CreateUserAccessToken"
UserService_DeleteUserAccessToken_FullMethodName = "/slash.api.v2.UserService/DeleteUserAccessToken"
@ -31,6 +32,8 @@ const (
type UserServiceClient interface {
// GetUser returns a user by id.
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error)
// CreateUser creates a new user.
CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error)
// ListUserAccessTokens returns a list of access tokens for a user.
ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error)
// CreateUserAccessToken creates a new access token for a user.
@ -56,6 +59,15 @@ func (c *userServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opt
return out, nil
}
func (c *userServiceClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) {
out := new(CreateUserResponse)
err := c.cc.Invoke(ctx, UserService_CreateUser_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *userServiceClient) ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error) {
out := new(ListUserAccessTokensResponse)
err := c.cc.Invoke(ctx, UserService_ListUserAccessTokens_FullMethodName, in, out, opts...)
@ -89,6 +101,8 @@ func (c *userServiceClient) DeleteUserAccessToken(ctx context.Context, in *Delet
type UserServiceServer interface {
// GetUser returns a user by id.
GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error)
// CreateUser creates a new user.
CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error)
// ListUserAccessTokens returns a list of access tokens for a user.
ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error)
// CreateUserAccessToken creates a new access token for a user.
@ -105,6 +119,9 @@ type UnimplementedUserServiceServer struct {
func (UnimplementedUserServiceServer) GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented")
}
func (UnimplementedUserServiceServer) CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented")
}
func (UnimplementedUserServiceServer) ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListUserAccessTokens not implemented")
}
@ -145,6 +162,24 @@ func _UserService_GetUser_Handler(srv interface{}, ctx context.Context, dec func
return interceptor(ctx, in, info, handler)
}
func _UserService_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(UserServiceServer).CreateUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: UserService_CreateUser_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(UserServiceServer).CreateUser(ctx, req.(*CreateUserRequest))
}
return interceptor(ctx, in, info, handler)
}
func _UserService_ListUserAccessTokens_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListUserAccessTokensRequest)
if err := dec(in); err != nil {
@ -210,6 +245,10 @@ var UserService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetUser",
Handler: _UserService_GetUser_Handler,
},
{
MethodName: "CreateUser",
Handler: _UserService_CreateUser_Handler,
},
{
MethodName: "ListUserAccessTokens",
Handler: _UserService_ListUserAccessTokens_Handler,

View File

@ -3,6 +3,9 @@
## Table of Contents
- [store/activity.proto](#store_activity-proto)
- [ActivityShorcutCreatePayload](#slash-store-ActivityShorcutCreatePayload)
- [store/common.proto](#store_common-proto)
- [RowStatus](#slash-store-RowStatus)
@ -23,6 +26,37 @@
<a name="store_activity-proto"></a>
<p align="right"><a href="#top">Top</a></p>
## store/activity.proto
<a name="slash-store-ActivityShorcutCreatePayload"></a>
### ActivityShorcutCreatePayload
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| shortcut_id | [int32](#int32) | | |
<a name="store_common-proto"></a>
<p align="right"><a href="#top">Top</a></p>

View File

@ -0,0 +1,153 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: store/activity.proto
package store
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ActivityShorcutCreatePayload struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ShortcutId int32 `protobuf:"varint,1,opt,name=shortcut_id,json=shortcutId,proto3" json:"shortcut_id,omitempty"`
}
func (x *ActivityShorcutCreatePayload) Reset() {
*x = ActivityShorcutCreatePayload{}
if protoimpl.UnsafeEnabled {
mi := &file_store_activity_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ActivityShorcutCreatePayload) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ActivityShorcutCreatePayload) ProtoMessage() {}
func (x *ActivityShorcutCreatePayload) ProtoReflect() protoreflect.Message {
mi := &file_store_activity_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ActivityShorcutCreatePayload.ProtoReflect.Descriptor instead.
func (*ActivityShorcutCreatePayload) Descriptor() ([]byte, []int) {
return file_store_activity_proto_rawDescGZIP(), []int{0}
}
func (x *ActivityShorcutCreatePayload) GetShortcutId() int32 {
if x != nil {
return x.ShortcutId
}
return 0
}
var File_store_activity_proto protoreflect.FileDescriptor
var file_store_activity_proto_rawDesc = []byte{
0x0a, 0x14, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74,
0x6f, 0x72, 0x65, 0x22, 0x3f, 0x0a, 0x1c, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53,
0x68, 0x6f, 0x72, 0x63, 0x75, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x5f,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x63,
0x75, 0x74, 0x49, 0x64, 0x42, 0x97, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61,
0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x0d, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69,
0x74, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c,
0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74,
0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x53, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73,
0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c,
0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74,
0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_store_activity_proto_rawDescOnce sync.Once
file_store_activity_proto_rawDescData = file_store_activity_proto_rawDesc
)
func file_store_activity_proto_rawDescGZIP() []byte {
file_store_activity_proto_rawDescOnce.Do(func() {
file_store_activity_proto_rawDescData = protoimpl.X.CompressGZIP(file_store_activity_proto_rawDescData)
})
return file_store_activity_proto_rawDescData
}
var file_store_activity_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_store_activity_proto_goTypes = []interface{}{
(*ActivityShorcutCreatePayload)(nil), // 0: slash.store.ActivityShorcutCreatePayload
}
var file_store_activity_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_store_activity_proto_init() }
func file_store_activity_proto_init() {
if File_store_activity_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_store_activity_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ActivityShorcutCreatePayload); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_store_activity_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_store_activity_proto_goTypes,
DependencyIndexes: file_store_activity_proto_depIdxs,
MessageInfos: file_store_activity_proto_msgTypes,
}.Build()
File_store_activity_proto = out.File
file_store_activity_proto_rawDesc = nil
file_store_activity_proto_goTypes = nil
file_store_activity_proto_depIdxs = nil
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
package slash.store;
option go_package = "gen/store";
message ActivityShorcutCreatePayload {
int32 shortcut_id = 1;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
resources/logo-pixel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
resources/logo128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

59
server/resource.go Normal file
View File

@ -0,0 +1,59 @@
package server
import (
"bytes"
"fmt"
"net/http"
"os"
"github.com/boojack/slash/server/profile"
"github.com/boojack/slash/store"
"github.com/h2non/filetype"
"github.com/labstack/echo/v4"
)
type ResourceService struct {
Profile *profile.Profile
Store *store.Store
}
func NewResourceService(profile *profile.Profile, store *store.Store) *ResourceService {
return &ResourceService{
Profile: profile,
Store: store,
}
}
// Register registers the resource service to the echo server.
func (s *ResourceService) Register(g *echo.Group) {
g.GET("/resources/:id", func(c echo.Context) error {
ctx := c.Request().Context()
resourceID := c.Param("resourceId")
resourceRelativePathSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
Key: store.WorkspaceResourceRelativePath,
})
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "failed to workspace resource relative path setting").SetInternal(err)
}
if resourceRelativePathSetting == nil || resourceRelativePathSetting.Value == "" {
return echo.NewHTTPError(http.StatusBadRequest, "found no workspace resource relative path setting")
}
resourceRelativePath := resourceRelativePathSetting.Value
resourcePath := fmt.Sprintf("%s/%s", resourceRelativePath, resourceID)
buf, err := os.ReadFile(resourcePath)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to read the local resource: %s", resourcePath)).SetInternal(err)
}
kind, err := filetype.Match(buf)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to match the local resource: %s", resourcePath)).SetInternal(err)
}
resourceMimeType := kind.MIME.Value
c.Response().Writer.Header().Set(echo.HeaderCacheControl, "max-age=31536000, immutable")
c.Response().Writer.Header().Set(echo.HeaderContentSecurityPolicy, "default-src 'self'")
c.Response().Writer.Header().Set("Content-Disposition", fmt.Sprintf(`filename="%s"`, resourceID))
return c.Stream(http.StatusOK, resourceMimeType, bytes.NewReader(buf))
})
}

View File

@ -76,6 +76,10 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
return nil, fmt.Errorf("failed to register gRPC gateway: %w", err)
}
// Register resource service.
resourceService := NewResourceService(profile, store)
resourceService.Register(rootGroup)
return s, nil
}
@ -111,6 +115,10 @@ func (s *Server) Shutdown(ctx context.Context) {
fmt.Printf("server stopped properly\n")
}
func (s *Server) GetEcho() *echo.Echo {
return s.e
}
func (s *Server) getSystemSecretSessionName(ctx context.Context) (string, error) {
secretSessionNameValue, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
Key: store.WorkspaceDisallowSignUp,

View File

@ -9,10 +9,10 @@ import (
// Version is the service current released version.
// Semantic versioning: https://semver.org/
var Version = "0.4.1"
var Version = "0.4.2"
// DevVersion is the service current development version.
var DevVersion = "0.4.1"
var DevVersion = "0.4.2"
func GetCurrentVersion(mode string) string {
if mode == "dev" || mode == "demo" {

View File

@ -59,3 +59,12 @@ CREATE TABLE activity (
level TEXT NOT NULL CHECK (level IN ('INFO', 'WARN', 'ERROR')) DEFAULT 'INFO',
payload TEXT NOT NULL DEFAULT '{}'
);
-- idp
CREATE TABLE idp (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
identifier_filter TEXT NOT NULL DEFAULT '',
config TEXT NOT NULL DEFAULT '{}'
);

View File

@ -0,0 +1,8 @@
-- idp
CREATE TABLE idp (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
identifier_filter TEXT NOT NULL DEFAULT '',
config TEXT NOT NULL DEFAULT '{}'
);

View File

@ -59,3 +59,12 @@ CREATE TABLE activity (
level TEXT NOT NULL CHECK (level IN ('INFO', 'WARN', 'ERROR')) DEFAULT 'INFO',
payload TEXT NOT NULL DEFAULT '{}'
);
-- idp
CREATE TABLE idp (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
identifier_filter TEXT NOT NULL DEFAULT '',
config TEXT NOT NULL DEFAULT '{}'
);

View File

@ -8,10 +8,12 @@ import (
type WorkspaceSettingKey string
const (
// WorkspaceDisallowSignUp is the key type for disallow sign up in workspace level.
WorkspaceDisallowSignUp WorkspaceSettingKey = "disallow-signup"
// WorkspaceSecretSessionName is the key type for secret session name.
WorkspaceSecretSessionName WorkspaceSettingKey = "secret-session-name"
// WorkspaceDisallowSignUp is the key type for disallow sign up in workspace level.
WorkspaceDisallowSignUp WorkspaceSettingKey = "disallow-signup"
// WorkspaceResourceRelativePath is the key type for resource relative path.
WorkspaceResourceRelativePath WorkspaceSettingKey = "resource-relative-path"
)
// String returns the string format of WorkspaceSettingKey type.

93
test/server/auth_test.go Normal file
View File

@ -0,0 +1,93 @@
package testserver
import (
"bytes"
"context"
"encoding/json"
"testing"
apiv1 "github.com/boojack/slash/api/v1"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
)
func TestAuthServer(t *testing.T) {
ctx := context.Background()
s, err := NewTestingServer(ctx, t)
require.NoError(t, err)
defer s.Shutdown(ctx)
signup := &apiv1.SignUpRequest{
Email: "slash@yourselfhosted.com",
Password: "testpassword",
}
user, err := s.postAuthSignUp(signup)
require.NoError(t, err)
require.Equal(t, signup.Email, user.Email)
signin := &apiv1.SignInRequest{
Email: "slash@yourselfhosted.com",
Password: "testpassword",
}
user, err = s.postAuthSignIn(signin)
require.NoError(t, err)
require.Equal(t, signup.Email, user.Email)
err = s.postLogout()
require.NoError(t, err)
}
func (s *TestingServer) postAuthSignUp(signup *apiv1.SignUpRequest) (*apiv1.User, error) {
rawData, err := json.Marshal(&signup)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal signup")
}
reader := bytes.NewReader(rawData)
body, err := s.post("/api/v1/auth/signup", reader, nil)
if err != nil {
return nil, errors.Wrap(err, "fail to post request")
}
buf := &bytes.Buffer{}
_, err = buf.ReadFrom(body)
if err != nil {
return nil, errors.Wrap(err, "fail to read response body")
}
user := &apiv1.User{}
if err = json.Unmarshal(buf.Bytes(), user); err != nil {
return nil, errors.Wrap(err, "fail to unmarshal post signup response")
}
return user, nil
}
func (s *TestingServer) postAuthSignIn(signip *apiv1.SignInRequest) (*apiv1.User, error) {
rawData, err := json.Marshal(&signip)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal signin")
}
reader := bytes.NewReader(rawData)
body, err := s.post("/api/v1/auth/signin", reader, nil)
if err != nil {
return nil, errors.Wrap(err, "fail to post request")
}
buf := &bytes.Buffer{}
_, err = buf.ReadFrom(body)
if err != nil {
return nil, errors.Wrap(err, "fail to read response body")
}
user := &apiv1.User{}
if err = json.Unmarshal(buf.Bytes(), user); err != nil {
return nil, errors.Wrap(err, "fail to unmarshal post signin response")
}
return user, nil
}
func (s *TestingServer) postLogout() error {
_, err := s.post("/api/v1/auth/logout", nil, nil)
if err != nil {
return errors.Wrap(err, "fail to post request")
}
return nil
}

178
test/server/server.go Normal file
View File

@ -0,0 +1,178 @@
package testserver
import (
"context"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"testing"
"time"
"github.com/boojack/slash/api/auth"
"github.com/boojack/slash/server"
"github.com/boojack/slash/server/profile"
"github.com/boojack/slash/store"
"github.com/boojack/slash/store/db"
"github.com/boojack/slash/test"
"github.com/pkg/errors"
// sqlite driver.
_ "modernc.org/sqlite"
)
type TestingServer struct {
server *server.Server
client *http.Client
profile *profile.Profile
cookie string
}
func NewTestingServer(ctx context.Context, t *testing.T) (*TestingServer, error) {
profile := test.GetTestingProfile(t)
db := db.NewDB(profile)
if err := db.Open(ctx); err != nil {
return nil, errors.Wrap(err, "failed to open db")
}
store := store.New(db.DBInstance, profile)
server, err := server.NewServer(ctx, profile, store)
if err != nil {
return nil, errors.Wrap(err, "failed to create server")
}
s := &TestingServer{
server: server,
client: &http.Client{},
profile: profile,
cookie: "",
}
errChan := make(chan error, 1)
go func() {
if err := s.server.Start(ctx); err != nil {
if err != http.ErrServerClosed {
errChan <- errors.Wrap(err, "failed to run main server")
}
}
}()
if err := s.waitForServerStart(errChan); err != nil {
return nil, errors.Wrap(err, "failed to start server")
}
return s, nil
}
func (s *TestingServer) Shutdown(ctx context.Context) {
s.server.Shutdown(ctx)
}
func (s *TestingServer) waitForServerStart(errChan <-chan error) error {
ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ticker.C:
if s == nil {
continue
}
e := s.server.GetEcho()
if e == nil {
continue
}
addr := e.ListenerAddr()
if addr != nil && strings.Contains(addr.String(), ":") {
return nil // was started
}
case err := <-errChan:
if err == http.ErrServerClosed {
return nil
}
return err
}
}
}
func (s *TestingServer) request(method, uri string, body io.Reader, params, header map[string]string) (io.ReadCloser, error) {
fullURL := fmt.Sprintf("http://localhost:%d%s", s.profile.Port, uri)
req, err := http.NewRequest(method, fullURL, body)
if err != nil {
return nil, errors.Wrapf(err, "fail to create a new %s request(%q)", method, fullURL)
}
for k, v := range header {
req.Header.Set(k, v)
}
q := url.Values{}
for k, v := range params {
q.Add(k, v)
}
if len(q) > 0 {
req.URL.RawQuery = q.Encode()
}
resp, err := s.client.Do(req)
if err != nil {
return nil, errors.Wrapf(err, "fail to send a %s request(%q)", method, fullURL)
}
if resp.StatusCode != http.StatusOK {
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "failed to read http response body")
}
return nil, errors.Errorf("http response error code %v body %q", resp.StatusCode, string(body))
}
if method == "POST" {
if strings.Contains(uri, "/api/v1/auth/signin") || strings.Contains(uri, "/api/v1/auth/signup") {
cookie := ""
h := resp.Header.Get("Set-Cookie")
parts := strings.Split(h, "; ")
for _, p := range parts {
if strings.HasPrefix(p, fmt.Sprintf("%s=", auth.AccessTokenCookieName)) {
cookie = p
break
}
}
if cookie == "" {
return nil, errors.Errorf("unable to find access token in the login response headers")
}
s.cookie = cookie
} else if strings.Contains(uri, "/api/v1/auth/logout") {
s.cookie = ""
}
}
return resp.Body, nil
}
// get sends a GET client request.
func (s *TestingServer) get(url string, params map[string]string) (io.ReadCloser, error) {
return s.request("GET", url, nil, params, map[string]string{
"Cookie": s.cookie,
})
}
// post sends a POST client request.
func (s *TestingServer) post(url string, body io.Reader, params map[string]string) (io.ReadCloser, error) {
return s.request("POST", url, body, params, map[string]string{
"Cookie": s.cookie,
})
}
// patch sends a PATCH client request.
func (s *TestingServer) patch(url string, body io.Reader, params map[string]string) (io.ReadCloser, error) {
return s.request("PATCH", url, body, params, map[string]string{
"Cookie": s.cookie,
})
}
// delete sends a DELETE client request.
func (s *TestingServer) delete(url string, params map[string]string) (io.ReadCloser, error) {
return s.request("DELETE", url, nil, params, map[string]string{
"Cookie": s.cookie,
})
}

View File

@ -0,0 +1,72 @@
package testserver
import (
"bytes"
"context"
"encoding/json"
"fmt"
"testing"
apiv1 "github.com/boojack/slash/api/v1"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
)
func TestShortcutServer(t *testing.T) {
ctx := context.Background()
s, err := NewTestingServer(ctx, t)
require.NoError(t, err)
defer s.Shutdown(ctx)
signup := &apiv1.SignUpRequest{
Email: "slash@yourselfhosted.com",
Password: "testpassword",
}
user, err := s.postAuthSignUp(signup)
require.NoError(t, err)
require.Equal(t, signup.Email, user.Email)
user, err = s.getCurrentUser()
require.NoError(t, err)
require.Equal(t, signup.Email, user.Email)
shortcutCreate := &apiv1.CreateShortcutRequest{
Name: "test",
Link: "https://google.com",
Visibility: apiv1.VisibilityPublic,
Tags: []string{},
}
shortcut, err := s.postShortcutCreate(shortcutCreate)
require.NoError(t, err)
require.Equal(t, shortcutCreate.Name, shortcut.Name)
require.Equal(t, shortcutCreate.Link, shortcut.Link)
err = s.deleteShortcut(shortcut.ID)
require.NoError(t, err)
}
func (s *TestingServer) postShortcutCreate(request *apiv1.CreateShortcutRequest) (*apiv1.Shortcut, error) {
rawData, err := json.Marshal(&request)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal shortcut create")
}
reader := bytes.NewReader(rawData)
body, err := s.post("/api/v1/shortcut", reader, nil)
if err != nil {
return nil, errors.Wrap(err, "fail to post request")
}
buf := &bytes.Buffer{}
_, err = buf.ReadFrom(body)
if err != nil {
return nil, errors.Wrap(err, "fail to read response body")
}
shortcut := &apiv1.Shortcut{}
if err = json.Unmarshal(buf.Bytes(), &shortcut); err != nil {
return nil, errors.Wrap(err, "fail to unmarshal post shortcut response")
}
return shortcut, nil
}
func (s *TestingServer) deleteShortcut(shortcutID int32) error {
_, err := s.delete(fmt.Sprintf("/api/v1/shortcut/%d", shortcutID), nil)
return err
}

103
test/server/user_test.go Normal file
View File

@ -0,0 +1,103 @@
package testserver
import (
"bytes"
"context"
"encoding/json"
"fmt"
"testing"
apiv1 "github.com/boojack/slash/api/v1"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
)
func TestUserServer(t *testing.T) {
ctx := context.Background()
s, err := NewTestingServer(ctx, t)
require.NoError(t, err)
defer s.Shutdown(ctx)
signup := &apiv1.SignUpRequest{
Email: "slash@yourselfhosted.com",
Password: "testpassword",
}
user, err := s.postAuthSignUp(signup)
require.NoError(t, err)
require.Equal(t, signup.Email, user.Email)
user, err = s.getCurrentUser()
require.NoError(t, err)
require.Equal(t, signup.Email, user.Email)
user, err = s.getUserByID(user.ID)
require.NoError(t, err)
require.Equal(t, signup.Email, user.Email)
newEmail := "test@usermemos.com"
userPatch := &apiv1.PatchUserRequest{
Email: &newEmail,
}
user, err = s.patchUser(user.ID, userPatch)
require.NoError(t, err)
require.Equal(t, newEmail, user.Email)
}
func (s *TestingServer) getCurrentUser() (*apiv1.User, error) {
body, err := s.get("/api/v1/user/me", nil)
if err != nil {
return nil, err
}
buf := &bytes.Buffer{}
_, err = buf.ReadFrom(body)
if err != nil {
return nil, errors.Wrap(err, "fail to read response body")
}
user := &apiv1.User{}
if err = json.Unmarshal(buf.Bytes(), &user); err != nil {
return nil, errors.Wrap(err, "fail to unmarshal get user response")
}
return user, nil
}
func (s *TestingServer) getUserByID(userID int32) (*apiv1.User, error) {
body, err := s.get(fmt.Sprintf("/api/v1/user/%d", userID), nil)
if err != nil {
return nil, err
}
buf := &bytes.Buffer{}
_, err = buf.ReadFrom(body)
if err != nil {
return nil, errors.Wrap(err, "fail to read response body")
}
user := &apiv1.User{}
if err = json.Unmarshal(buf.Bytes(), &user); err != nil {
return nil, errors.Wrap(err, "fail to unmarshal get user response")
}
return user, nil
}
func (s *TestingServer) patchUser(userID int32, request *apiv1.PatchUserRequest) (*apiv1.User, error) {
rawData, err := json.Marshal(&request)
if err != nil {
return nil, errors.Wrap(err, "failed to marshal request")
}
reader := bytes.NewReader(rawData)
body, err := s.patch(fmt.Sprintf("/api/v1/user/%d", userID), reader, nil)
if err != nil {
return nil, err
}
buf := &bytes.Buffer{}
_, err = buf.ReadFrom(body)
if err != nil {
return nil, errors.Wrap(err, "fail to read response body")
}
user := &apiv1.User{}
if err = json.Unmarshal(buf.Bytes(), user); err != nil {
return nil, errors.Wrap(err, "fail to unmarshal patch user response")
}
return user, nil
}

View File

@ -1,4 +1,4 @@
package tests
package test
import (
"fmt"

View File

@ -55,7 +55,7 @@ const ShortcutView = (props: Props) => {
<div className="w-full flex flex-row justify-start items-center">
<a
className={classNames(
"max-w-[calc(100%-24px) flex flex-row px-1 mr-1 justify-start items-center cursor-pointer rounded-md hover:bg-gray-100 hover:shadow"
"max-w-[calc(100%-36px)] flex flex-row px-1 mr-1 justify-start items-center cursor-pointer rounded-md hover:bg-gray-100 hover:shadow"
)}
target="_blank"
href={shortcutLink}

View File

@ -236,3 +236,51 @@ export declare class GetShortcutResponse extends Message<GetShortcutResponse> {
static equals(a: GetShortcutResponse | PlainMessage<GetShortcutResponse> | undefined, b: GetShortcutResponse | PlainMessage<GetShortcutResponse> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.CreateShortcutRequest
*/
export declare class CreateShortcutRequest extends Message<CreateShortcutRequest> {
/**
* @generated from field: slash.api.v2.Shortcut shortcut = 1;
*/
shortcut?: Shortcut;
constructor(data?: PartialMessage<CreateShortcutRequest>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.api.v2.CreateShortcutRequest";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateShortcutRequest;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateShortcutRequest;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateShortcutRequest;
static equals(a: CreateShortcutRequest | PlainMessage<CreateShortcutRequest> | undefined, b: CreateShortcutRequest | PlainMessage<CreateShortcutRequest> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.CreateShortcutResponse
*/
export declare class CreateShortcutResponse extends Message<CreateShortcutResponse> {
/**
* @generated from field: slash.api.v2.Shortcut shortcut = 1;
*/
shortcut?: Shortcut;
constructor(data?: PartialMessage<CreateShortcutResponse>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.api.v2.CreateShortcutResponse";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateShortcutResponse;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateShortcutResponse;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateShortcutResponse;
static equals(a: CreateShortcutResponse | PlainMessage<CreateShortcutResponse> | undefined, b: CreateShortcutResponse | PlainMessage<CreateShortcutResponse> | undefined): boolean;
}

View File

@ -90,3 +90,23 @@ export const GetShortcutResponse = proto3.makeMessageType(
],
);
/**
* @generated from message slash.api.v2.CreateShortcutRequest
*/
export const CreateShortcutRequest = proto3.makeMessageType(
"slash.api.v2.CreateShortcutRequest",
() => [
{ no: 1, name: "shortcut", kind: "message", T: Shortcut },
],
);
/**
* @generated from message slash.api.v2.CreateShortcutResponse
*/
export const CreateShortcutResponse = proto3.makeMessageType(
"slash.api.v2.CreateShortcutResponse",
() => [
{ no: 1, name: "shortcut", kind: "message", T: Shortcut },
],
);

View File

@ -66,6 +66,11 @@ export declare class User extends Message<User> {
*/
nickname: string;
/**
* @generated from field: string password = 9;
*/
password: string;
constructor(data?: PartialMessage<User>);
static readonly runtime: typeof proto3;
@ -129,6 +134,54 @@ export declare class GetUserResponse extends Message<GetUserResponse> {
static equals(a: GetUserResponse | PlainMessage<GetUserResponse> | undefined, b: GetUserResponse | PlainMessage<GetUserResponse> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.CreateUserRequest
*/
export declare class CreateUserRequest extends Message<CreateUserRequest> {
/**
* @generated from field: slash.api.v2.User user = 1;
*/
user?: User;
constructor(data?: PartialMessage<CreateUserRequest>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.api.v2.CreateUserRequest";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateUserRequest;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateUserRequest;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateUserRequest;
static equals(a: CreateUserRequest | PlainMessage<CreateUserRequest> | undefined, b: CreateUserRequest | PlainMessage<CreateUserRequest> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.CreateUserResponse
*/
export declare class CreateUserResponse extends Message<CreateUserResponse> {
/**
* @generated from field: slash.api.v2.User user = 1;
*/
user?: User;
constructor(data?: PartialMessage<CreateUserResponse>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.api.v2.CreateUserResponse";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): CreateUserResponse;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): CreateUserResponse;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): CreateUserResponse;
static equals(a: CreateUserResponse | PlainMessage<CreateUserResponse> | undefined, b: CreateUserResponse | PlainMessage<CreateUserResponse> | undefined): boolean;
}
/**
* @generated from message slash.api.v2.ListUserAccessTokensRequest
*/

View File

@ -31,6 +31,7 @@ export const User = proto3.makeMessageType(
{ no: 6, name: "role", kind: "enum", T: proto3.getEnumType(Role) },
{ no: 7, name: "email", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 8, name: "nickname", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 9, name: "password", kind: "scalar", T: 9 /* ScalarType.STRING */ },
],
);
@ -54,6 +55,26 @@ export const GetUserResponse = proto3.makeMessageType(
],
);
/**
* @generated from message slash.api.v2.CreateUserRequest
*/
export const CreateUserRequest = proto3.makeMessageType(
"slash.api.v2.CreateUserRequest",
() => [
{ no: 1, name: "user", kind: "message", T: User },
],
);
/**
* @generated from message slash.api.v2.CreateUserResponse
*/
export const CreateUserResponse = proto3.makeMessageType(
"slash.api.v2.CreateUserResponse",
() => [
{ no: 1, name: "user", kind: "message", T: User },
],
);
/**
* @generated from message slash.api.v2.ListUserAccessTokensRequest
*/

View File

@ -0,0 +1,32 @@
// @generated by protoc-gen-es v1.3.0
// @generated from file store/activity.proto (package slash.store, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3 } from "@bufbuild/protobuf";
/**
* @generated from message slash.store.ActivityShorcutCreatePayload
*/
export declare class ActivityShorcutCreatePayload extends Message<ActivityShorcutCreatePayload> {
/**
* @generated from field: int32 shortcut_id = 1;
*/
shortcutId: number;
constructor(data?: PartialMessage<ActivityShorcutCreatePayload>);
static readonly runtime: typeof proto3;
static readonly typeName = "slash.store.ActivityShorcutCreatePayload";
static readonly fields: FieldList;
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ActivityShorcutCreatePayload;
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ActivityShorcutCreatePayload;
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ActivityShorcutCreatePayload;
static equals(a: ActivityShorcutCreatePayload | PlainMessage<ActivityShorcutCreatePayload> | undefined, b: ActivityShorcutCreatePayload | PlainMessage<ActivityShorcutCreatePayload> | undefined): boolean;
}

View File

@ -0,0 +1,17 @@
// @generated by protoc-gen-es v1.3.0
// @generated from file store/activity.proto (package slash.store, syntax proto3)
/* eslint-disable */
// @ts-nocheck
import { proto3 } from "@bufbuild/protobuf";
/**
* @generated from message slash.store.ActivityShorcutCreatePayload
*/
export const ActivityShorcutCreatePayload = proto3.makeMessageType(
"slash.store.ActivityShorcutCreatePayload",
() => [
{ no: 1, name: "shortcut_id", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
],
);