Skip to content

Commit 0acd42e

Browse files
mustard-mhjeanp413svenefftinge
authored
Migrate gRPC VerificationService (#19143)
* Implement * use on dashboard * Add test case * fixup * fix build * Update proto * Update * 💄 * 💄 * [verificationservice] added mock impl for previews --------- Co-authored-by: Jean Pierre Huaroto <jeanp413@hotmail.com> Co-authored-by: Sven Efftinge <sven@gitpod.io>
1 parent ab797f1 commit 0acd42e

File tree

16 files changed

+1315
-126
lines changed

16 files changed

+1315
-126
lines changed

components/dashboard/src/data/setup.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ import * as ConfigurationClasses from "@gitpod/public-api/lib/gitpod/v1/configur
2424
import * as AuthProviderClasses from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb";
2525
import * as EnvVarClasses from "@gitpod/public-api/lib/gitpod/v1/envvar_pb";
2626
import * as PrebuildClasses from "@gitpod/public-api/lib/gitpod/v1/prebuild_pb";
27+
import * as VerificationClasses from "@gitpod/public-api/lib/gitpod/v1/verification_pb";
2728
import * as SCMClasses from "@gitpod/public-api/lib/gitpod/v1/scm_pb";
2829
import * as SSHClasses from "@gitpod/public-api/lib/gitpod/v1/ssh_pb";
2930

3031
// This is used to version the cache
3132
// If data we cache changes in a non-backwards compatible way, increment this version
3233
// That will bust any previous cache versions a client may have stored
33-
const CACHE_VERSION = "8";
34+
const CACHE_VERSION = "9";
3435

3536
export function noPersistence(queryKey: QueryKey): QueryKey {
3637
return [...queryKey, "no-persistence"];
@@ -152,6 +153,7 @@ function initializeMessages() {
152153
...Object.values(AuthProviderClasses),
153154
...Object.values(EnvVarClasses),
154155
...Object.values(PrebuildClasses),
156+
...Object.values(VerificationClasses),
155157
...Object.values(SCMClasses),
156158
...Object.values(SSHClasses),
157159
];
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Copyright (c) 2023 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License.AGPL.txt in the project root for license information.
5+
*/
6+
7+
import { CallOptions, PromiseClient } from "@connectrpc/connect";
8+
import { PartialMessage } from "@bufbuild/protobuf";
9+
import { VerificationService } from "@gitpod/public-api/lib/gitpod/v1/verification_connect";
10+
import {
11+
SendPhoneNumberVerificationTokenRequest,
12+
SendPhoneNumberVerificationTokenResponse,
13+
VerifyPhoneNumberVerificationTokenRequest,
14+
VerifyPhoneNumberVerificationTokenResponse,
15+
} from "@gitpod/public-api/lib/gitpod/v1/verification_pb";
16+
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
17+
import { getGitpodService } from "./service";
18+
import { validate as uuidValidate } from "uuid";
19+
20+
export class JsonRpcVerificationClient implements PromiseClient<typeof VerificationService> {
21+
async sendPhoneNumberVerificationToken(
22+
request: PartialMessage<SendPhoneNumberVerificationTokenRequest>,
23+
_options?: CallOptions | undefined,
24+
): Promise<SendPhoneNumberVerificationTokenResponse> {
25+
if (!request.phoneNumber) {
26+
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "phoneNumber is required");
27+
}
28+
const info = await getGitpodService().server.sendPhoneNumberVerificationToken(request.phoneNumber);
29+
return new SendPhoneNumberVerificationTokenResponse({
30+
verificationId: info.verificationId,
31+
});
32+
}
33+
34+
async verifyPhoneNumberVerificationToken(
35+
request: PartialMessage<VerifyPhoneNumberVerificationTokenRequest>,
36+
_options?: CallOptions | undefined,
37+
): Promise<VerifyPhoneNumberVerificationTokenResponse> {
38+
if (!request.phoneNumber) {
39+
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "phoneNumber is required");
40+
}
41+
if (!request.verificationId || !uuidValidate(request.verificationId)) {
42+
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "verificationId is required");
43+
}
44+
if (!request.token) {
45+
throw new ApplicationError(ErrorCodes.BAD_REQUEST, "token is required");
46+
}
47+
const info = await getGitpodService().server.verifyPhoneNumberVerificationToken(
48+
request.phoneNumber,
49+
request.token,
50+
request.verificationId,
51+
);
52+
return new VerifyPhoneNumberVerificationTokenResponse({
53+
verified: info,
54+
});
55+
}
56+
}

components/dashboard/src/service/public-api.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import { JsonRpcScmClient } from "./json-rpc-scm-client";
3636
import { SCMService } from "@gitpod/public-api/lib/gitpod/v1/scm_connect";
3737
import { SSHService } from "@gitpod/public-api/lib/gitpod/v1/ssh_connect";
3838
import { JsonRpcSSHClient } from "./json-rpc-ssh-client";
39+
import { JsonRpcVerificationClient } from "./json-rpc-verification-client";
40+
import { VerificationService } from "@gitpod/public-api/lib/gitpod/v1/verification_connect";
3941

4042
const transport = createConnectTransport({
4143
baseUrl: `${window.location.protocol}//${window.location.host}/public-api`,
@@ -91,6 +93,11 @@ export const sshClient = createServiceClient(SSHService, {
9193
featureFlagSuffix: "ssh",
9294
});
9395

96+
export const verificationClient = createServiceClient(VerificationService, {
97+
client: new JsonRpcVerificationClient(),
98+
featureFlagSuffix: "verification",
99+
});
100+
94101
export async function listAllProjects(opts: { orgId: string }): Promise<ProtocolProject[]> {
95102
let pagination = {
96103
page: 1,

components/dashboard/src/start/VerifyModal.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
import { useState } from "react";
88
import Alert, { AlertType } from "../components/Alert";
99
import Modal, { ModalBody, ModalFooter, ModalHeader } from "../components/Modal";
10-
import { getGitpodService } from "../service/service";
1110
import PhoneInput from "react-intl-tel-input";
1211
import "react-intl-tel-input/dist/main.css";
1312
import "./phone-input.css";
1413
import { Button } from "../components/Button";
1514
import { LinkButton } from "../components/LinkButton";
1615
import { useFeatureFlag } from "../data/featureflag-query";
16+
import { verificationClient } from "../service/public-api";
1717

1818
interface VerifyModalState {
1919
phoneNumber?: string;
@@ -41,7 +41,9 @@ export function VerifyModal() {
4141
message: undefined,
4242
sending: true,
4343
});
44-
const resp = await getGitpodService().server.sendPhoneNumberVerificationToken(state.phoneNumber || "");
44+
const resp = await verificationClient.sendPhoneNumberVerificationToken({
45+
phoneNumber: state.phoneNumber || "",
46+
});
4547
setVerificationId(resp.verificationId);
4648
setState({
4749
...state,
@@ -123,11 +125,12 @@ export function VerifyModal() {
123125
};
124126
const verifyToken = async () => {
125127
try {
126-
const verified = await getGitpodService().server.verifyPhoneNumberVerificationToken(
127-
state.phoneNumber!,
128-
state.token!,
128+
const resp = await verificationClient.verifyPhoneNumberVerificationToken({
129129
verificationId,
130-
);
130+
token: state.token,
131+
phoneNumber: state.phoneNumber,
132+
});
133+
const verified = resp.verified;
131134
if (verified) {
132135
setState({
133136
...state,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
syntax = "proto3";
2+
3+
package gitpod.v1;
4+
5+
option go_package = "github.com/gitpod-io/gitpod/components/public-api/go/v1";
6+
7+
service VerificationService {
8+
// SendPhoneNumberVerificationToken sends a verification token to the
9+
// specified phone number.
10+
rpc SendPhoneNumberVerificationToken(SendPhoneNumberVerificationTokenRequest) returns (SendPhoneNumberVerificationTokenResponse) {}
11+
12+
// VerifyPhoneNumberVerificationToken verifies the specified verification
13+
// token.
14+
rpc VerifyPhoneNumberVerificationToken(VerifyPhoneNumberVerificationTokenRequest) returns (VerifyPhoneNumberVerificationTokenResponse) {}
15+
}
16+
17+
// Required fields:
18+
// - phone_number
19+
message SendPhoneNumberVerificationTokenRequest {
20+
// phone_number in E.164 format
21+
string phone_number = 1;
22+
}
23+
24+
message SendPhoneNumberVerificationTokenResponse {
25+
// verification_id is used to VerifyPhoneNumberVerificationToken
26+
string verification_id = 1;
27+
}
28+
29+
// Required fields:
30+
// - phone_number
31+
// - verification_id
32+
// - token
33+
message VerifyPhoneNumberVerificationTokenRequest {
34+
// phone_number in E.164 format
35+
string phone_number = 1;
36+
// verification_id is returned by SendPhoneNumberVerificationToken
37+
string verification_id = 2;
38+
// token is the verification token from providers
39+
string token = 3;
40+
}
41+
42+
message VerifyPhoneNumberVerificationTokenResponse {
43+
// verified indicates if the verification was successful
44+
bool verified = 1;
45+
}

components/public-api/go/v1/v1connect/verification.connect.go

Lines changed: 122 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/public-api/go/v1/v1connect/verification.proxy.connect.go

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)