@gitpod/gitpod-protocol 0.1.5-pd-metrics.33 → 0.1.5-pd-gen47-patch-test.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,6 +24,8 @@ import {
24
24
  GuessGitTokenScopesParams,
25
25
  GuessedGitTokenScopes,
26
26
  ProjectEnvVar,
27
+ UserSSHPublicKeyValue,
28
+ SSHPublicKeyValue,
27
29
  } from "./protocol";
28
30
  import {
29
31
  Team,
@@ -47,7 +49,12 @@ import { LicenseService } from "./license-protocol";
47
49
  import { Emitter } from "./util/event";
48
50
  import { AccountStatement, CreditAlert } from "./accounting-protocol";
49
51
  import { GithubUpgradeURL, PlanCoupon } from "./payment-protocol";
50
- import { TeamSubscription, TeamSubscriptionSlot, TeamSubscriptionSlotResolved } from "./team-subscription-protocol";
52
+ import {
53
+ TeamSubscription,
54
+ TeamSubscription2,
55
+ TeamSubscriptionSlot,
56
+ TeamSubscriptionSlotResolved,
57
+ } from "./team-subscription-protocol";
51
58
  import { RemotePageMessage, RemoteTrackMessage, RemoteIdentifyMessage } from "./analytics";
52
59
  import { IDEServer } from "./ide-protocol";
53
60
  import { InstallationAdminSettings, TelemetryData } from "./installation-admin-protocol";
@@ -142,6 +149,12 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
142
149
  setEnvVar(variable: UserEnvVarValue): Promise<void>;
143
150
  deleteEnvVar(variable: UserEnvVarValue): Promise<void>;
144
151
 
152
+ // User SSH Keys
153
+ hasSSHPublicKey(): Promise<boolean>;
154
+ getSSHPublicKeys(): Promise<UserSSHPublicKeyValue[]>;
155
+ addSSHPublicKey(value: SSHPublicKeyValue): Promise<UserSSHPublicKeyValue>;
156
+ deleteSSHPublicKey(id: string): Promise<void>;
157
+
145
158
  // Teams
146
159
  getTeams(): Promise<Team[]>;
147
160
  getTeamMembers(teamId: string): Promise<TeamMemberInfo[]>;
@@ -235,7 +248,9 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
235
248
  */
236
249
  getChargebeeSiteId(): Promise<string>;
237
250
  createPortalSession(): Promise<{}>;
251
+ createTeamPortalSession(teamId: string): Promise<{}>;
238
252
  checkout(planId: string, planQuantity?: number): Promise<{}>;
253
+ teamCheckout(teamId: string, planId: string): Promise<{}>;
239
254
  getAvailableCoupons(): Promise<PlanCoupon[]>;
240
255
  getAppliedCoupons(): Promise<PlanCoupon[]>;
241
256
 
@@ -247,6 +262,7 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
247
262
  subscriptionCancel(subscriptionId: string): Promise<void>;
248
263
  subscriptionCancelDowngrade(subscriptionId: string): Promise<void>;
249
264
 
265
+ getTeamSubscription(teamId: string): Promise<TeamSubscription2 | undefined>;
250
266
  tsGet(): Promise<TeamSubscription[]>;
251
267
  tsGetSlots(): Promise<TeamSubscriptionSlotResolved[]>;
252
268
  tsGetUnassignedSlot(teamSubscriptionId: string): Promise<TeamSubscriptionSlot | undefined>;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Copyright (c) 2020 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 { suite, test } from "mocha-typescript";
8
+ import * as chai from "chai";
9
+ import { SSHPublicKeyValue } from ".";
10
+
11
+ const expect = chai.expect;
12
+
13
+ @suite
14
+ class TestSSHPublicKeyValue {
15
+ private key =
16
+ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDCnrN9UdK1bNGPmZfenTWXLuYYDjlYvZE8S+WOfP08WpR1GETzX5ZvgYOEZGwEE8KUPHC9cge4Hvo/ydIS9aqbZ5MiVGJ8cAIq1Ic89SjlDWU6fl8TwIqOPCi2imAASlEDP4q8vMLK1N6UOW1EVbxyL3uybGd10ysC1t1FxFPveIGNsYE/MOQeuEWS16AplpXYXIfVRSlgAskeBft2w8Ud3B4gNe8ECLA/FXu96UpvZkdtOarA3JZ9Z27GveNJg9Mtmmw0+US0KXiO9x9NyH7G8+mqVDwDY+nNvaFA5gtQxkkl/uY2oz9k/B4Rjlj3jOiUXe5uQs3XUm5m8g9a9fh62DabLpA2fEvtfg+a/VqNe52dNa5YjupwvBd6Inb5uMW/TYjNl6bNHPlXFKw/nwLOVzukpkjxMZUKS6+4BGkpoasj6y2rTU/wkpbdD8J7yjI1p6J9aKkC6KksIWgN7xGmHkv2PCGDqMHTNbnQyowtNKMgA/667vAYJ0qW7HAHBFXJRs6uRi/DI3+c1QV2s4wPCpEHDIYApovQ0fbON4WDPoGMyHd7kPh9xB/bX7Dj0uMXImu1pdTd62fQ/1XXX64+vjAAXS/P9RSCD0RCRt/K3LPKl2m7GPI3y1niaE52XhxZw+ms9ays6NasNVMw/ZC+f02Ti+L5FBEVf8230RVVRQ== notfound@gitpod.io";
17
+
18
+ @test public testValidate() {
19
+ const key = this.key;
20
+ const [t, k, e] = key.split(" ");
21
+ expect(
22
+ SSHPublicKeyValue.getData({
23
+ key,
24
+ name: "NiceName",
25
+ }),
26
+ ).to.deep.equal({ type: t, key: k, email: e });
27
+ }
28
+
29
+ @test public testValidateWithDiffType() {
30
+ const key = this.key;
31
+ const [_, k, e] = key.split(" ");
32
+ expect(
33
+ SSHPublicKeyValue.getData({
34
+ key: key.replace("ssh-rsa", "sk-ecdsa-sha2-nistp256@openssh.com"),
35
+ name: "NiceName",
36
+ }),
37
+ ).to.deep.equal({ type: "sk-ecdsa-sha2-nistp256@openssh.com", key: k, email: e });
38
+ }
39
+
40
+ @test public testValidateWithoutEmail() {
41
+ const key = this.key;
42
+ const [t, k, _] = key.split(" ");
43
+ expect(
44
+ SSHPublicKeyValue.getData({
45
+ key: key.replace(" notfound@gitpod.io", ""),
46
+ name: "NiceName",
47
+ }),
48
+ ).to.deep.equal({ type: t, key: k, email: undefined });
49
+ }
50
+
51
+ @test public testValidateWithoutEmailButEndsWithSpaces() {
52
+ const key = this.key;
53
+ const [t, k, _] = key.split(" ");
54
+ expect(
55
+ SSHPublicKeyValue.getData({
56
+ key: key.replace("notfound@gitpod.io", " "),
57
+ name: "NiceName",
58
+ }),
59
+ ).to.deep.equal({ type: t, key: k, email: undefined });
60
+ }
61
+
62
+ @test public testValidateWithError() {
63
+ expect(() =>
64
+ SSHPublicKeyValue.getData({
65
+ key: "Hello World",
66
+ name: "NiceName",
67
+ }),
68
+ ).throw("Key is invalid");
69
+
70
+ expect(() =>
71
+ SSHPublicKeyValue.getData({
72
+ key: "",
73
+ name: "NiceName",
74
+ }),
75
+ ).throw("Key is invalid");
76
+ }
77
+
78
+ @test public testGetFingerprint() {
79
+ const key = this.key;
80
+ expect(
81
+ SSHPublicKeyValue.getFingerprint({
82
+ key,
83
+ name: "NiceName",
84
+ }),
85
+ ).to.equal("ykjP/b5aqoa3envmXzWpPMCGgEFMu3QvubfSTNrJCMA=");
86
+ }
87
+
88
+ @test public testGetFingerprintWithIncorrectPublicKey() {
89
+ expect(() =>
90
+ SSHPublicKeyValue.getFingerprint({
91
+ key: "Hello World",
92
+ name: "NiceName",
93
+ }),
94
+ ).to.throw("Key is invalid");
95
+ }
96
+ }
97
+ module.exports = new TestSSHPublicKeyValue(); // Only to circumvent no usage warning :-/
package/src/protocol.ts CHANGED
@@ -242,12 +242,18 @@ export namespace UserEnvVar {
242
242
  if (name.trim() === "") {
243
243
  return "Name must not be empty.";
244
244
  }
245
+ if (name.length > 255) {
246
+ return "Name too long. Maximum name length is 255 characters.";
247
+ }
245
248
  if (!/^[a-zA-Z_]+[a-zA-Z0-9_]*$/.test(name)) {
246
249
  return "Name must match /^[a-zA-Z_]+[a-zA-Z0-9_]*$/.";
247
250
  }
248
251
  if (variable.value.trim() === "") {
249
252
  return "Value must not be empty.";
250
253
  }
254
+ if (variable.value.length > 32767) {
255
+ return "Value too long. Maximum value length is 32767 characters.";
256
+ }
251
257
  if (pattern.trim() === "") {
252
258
  return "Scope must not be empty.";
253
259
  }
@@ -350,6 +356,68 @@ export namespace UserEnvVar {
350
356
  }
351
357
  }
352
358
 
359
+ export interface SSHPublicKeyValue {
360
+ name: string;
361
+ key: string;
362
+ }
363
+ export interface UserSSHPublicKey extends SSHPublicKeyValue {
364
+ id: string;
365
+ key: string;
366
+ userId: string;
367
+ fingerprint: string;
368
+ creationTime: string;
369
+ lastUsedTime?: string;
370
+ }
371
+
372
+ export type UserSSHPublicKeyValue = Omit<UserSSHPublicKey, "key" | "userId">;
373
+
374
+ export namespace SSHPublicKeyValue {
375
+ export function validate(value: SSHPublicKeyValue): string | undefined {
376
+ if (value.name.length === 0) {
377
+ return "Title must not be empty.";
378
+ }
379
+ if (value.name.length > 255) {
380
+ return "Title too long. Maximum value length is 255 characters.";
381
+ }
382
+ if (value.key.length === 0) {
383
+ return "Key must not be empty.";
384
+ }
385
+ try {
386
+ getData(value);
387
+ } catch (e) {
388
+ return "Key is invalid. You must supply a key in OpenSSH public key format.";
389
+ }
390
+ return;
391
+ }
392
+
393
+ export function getData(value: SSHPublicKeyValue) {
394
+ // Begins with 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'ssh-ed25519', 'sk-ecdsa-sha2-nistp256@openssh.com', or 'sk-ssh-ed25519@openssh.com'.
395
+ const regex =
396
+ /^(?<type>ssh-rsa|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521|ssh-ed25519|sk-ecdsa-sha2-nistp256@openssh\.com|sk-ssh-ed25519@openssh\.com) (?<key>.*?)( (?<email>.*?))?$/;
397
+ const resultGroup = regex.exec(value.key.trim());
398
+ if (!resultGroup) {
399
+ throw new Error("Key is invalid.");
400
+ }
401
+ return {
402
+ type: resultGroup.groups?.["type"] as string,
403
+ key: resultGroup.groups?.["key"] as string,
404
+ email: resultGroup.groups?.["email"] || undefined,
405
+ };
406
+ }
407
+
408
+ export function getFingerprint(value: SSHPublicKeyValue) {
409
+ const data = getData(value);
410
+ let buf = Buffer.from(data.key, "base64");
411
+ // gitlab style
412
+ // const hash = createHash("md5").update(buf).digest("hex");
413
+ // github style
414
+ const hash = createHash("sha256").update(buf).digest("base64");
415
+ return hash;
416
+ }
417
+
418
+ export const MAXIMUM_KEY_LENGTH = 5;
419
+ }
420
+
353
421
  export interface GitpodToken {
354
422
  /** Hash value (SHA256) of the token (primary key). */
355
423
  tokenHash: string;
@@ -482,6 +550,12 @@ export interface Snapshot {
482
550
  message?: string;
483
551
  }
484
552
 
553
+ export interface VolumeSnapshot {
554
+ id: string;
555
+ creationTime: string;
556
+ volumeHandle: string;
557
+ }
558
+
485
559
  export type SnapshotState = "pending" | "available" | "error";
486
560
 
487
561
  export interface LayoutData {
@@ -866,6 +940,7 @@ export namespace ExternalImageConfigFile {
866
940
 
867
941
  export interface WorkspaceContext {
868
942
  title: string;
943
+ ref?: string;
869
944
  /** This contains the URL portion of the contextURL (which might contain other modifiers as well). It's optional because it's not set for older workspaces. */
870
945
  normalizedContextURL?: string;
871
946
  forceCreateNewWorkspace?: boolean;
@@ -33,6 +33,30 @@ export namespace TeamSubscription {
33
33
  };
34
34
  }
35
35
 
36
+ export interface TeamSubscription2 {
37
+ id: string;
38
+ teamId: string;
39
+ planId: string;
40
+ startDate: string;
41
+ endDate?: string;
42
+ quantity: number;
43
+ /** The Chargebee subscription id */
44
+ paymentReference: string;
45
+ cancellationDate?: string;
46
+ excludeFromMoreResources: boolean;
47
+ }
48
+
49
+ export namespace TeamSubscription2 {
50
+ export const create = (ts2: Omit<TeamSubscription2, "id">): TeamSubscription2 => {
51
+ const withId = ts2 as TeamSubscription2;
52
+ withId.id = uuidv4();
53
+ return withId;
54
+ };
55
+ export const isActive = (ts2: TeamSubscription2, date: string): boolean => {
56
+ return ts2.startDate <= date && (ts2.endDate === undefined || date < ts2.endDate);
57
+ };
58
+ }
59
+
36
60
  /**
37
61
  * A slot represents one unit of a TeamSubscription that gets assigned to one user at a time
38
62
  */
package/src/wsready.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * See License-AGPL.txt in the project root for license information.
5
5
  */
6
6
 
7
- // generated using github.com/32leaves/bel on 2022-03-29 17:08:06.113873917 +0000 UTC m=+0.010035965
7
+ // generated using github.com/32leaves/bel on 2022-05-18 18:19:49.011672619 +0000 UTC m=+0.006607361
8
8
  // DO NOT MODIFY
9
9
 
10
10
  export enum WorkspaceInitSource {