Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.9.0] - 2025-01-21
- Removed button "View this repo on the Web" from PopUps and Side Panel

## [4.8.0] - 2025-01-17
- Adding repository to Org/Team during "Connect Repository"

## [4.7.0] - 2025-01-08
- Resetting user session upon Logout

## [4.6.0] - 2024-12-25
- Switching off daily-activity-alert since we now have Slack Alerts enabled

Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "CodeSync",
"description": "CodeSync's AI-generated summaries provide clear, insightful coding overviews directly in your IDE, keeping your team aligned without manual tracking. Seamlessly integrate with GitHub and Slack to streamline your workflow.",
"icon": "images/icon.png",
"version": "4.6.0",
"version": "4.9.0",
"publisher": "codesync",
"engines": {
"vscode": "^1.86.0",
Expand Down Expand Up @@ -172,23 +172,23 @@
},
{
"view": "codesync-repo-connected",
"contents": "Repo is in sync with CodeSync.\n[View this repo on the web](command:codesync.trackRepo)\n[View Dashboard](command:codesync.viewDashboard)\n[Disconnect repo](command:codesync.disconnectRepo)\n[Logout](command:codesync.logout)"
"contents": "Repo is in sync with CodeSync.\n[View Dashboard](command:codesync.viewDashboard)\n[Disconnect repo](command:codesync.disconnectRepo)\n[Logout](command:codesync.logout)"
},
{
"view": "codesync-upgrade-to-pro-plan",
"contents": "Repo is in sync with CodeSync.\n[View this repo on the web](command:codesync.trackRepo)\n[Upgrade plan](command:codesync.upgradePlan)\n[View Dashboard](command:codesync.viewDashboard)\n[Disconnect repo](command:codesync.disconnectRepo)\n[Logout](command:codesync.logout)"
"contents": "Repo is in sync with CodeSync.\n[Upgrade plan](command:codesync.upgradePlan)\n[View Dashboard](command:codesync.viewDashboard)\n[Disconnect repo](command:codesync.disconnectRepo)\n[Logout](command:codesync.logout)"
},
{
"view": "codesync-try-pro-for-free",
"contents": "Repo is in sync with CodeSync.\n[View this repo on the web](command:codesync.trackRepo)\n[Upgrade plan for free](command:codesync.upgradePlan)\n[View Dashboard](command:codesync.viewDashboard)\n[Disconnect repo](command:codesync.disconnectRepo)\n[Logout](command:codesync.logout)"
"contents": "Repo is in sync with CodeSync.\n[Upgrade plan for free](command:codesync.upgradePlan)\n[View Dashboard](command:codesync.viewDashboard)\n[Disconnect repo](command:codesync.disconnectRepo)\n[Logout](command:codesync.logout)"
},
{
"view": "codesync-opened-repo-is-sub-dir-of-connected-repo",
"contents": "You are good to go ✅.\nCurrent directory is in sync with CodeSync because a parent repo is in sync.\n[View parent repo on web](command:codesync.trackRepo)\n[Disconnect parent repo](command:codesync.disconnectRepo)\n[View Dashboard](command:codesync.viewDashboard)\n[Logout](command:codesync.logout)"
"contents": "You are good to go ✅.\nCurrent directory is in sync with CodeSync because a parent repo is in sync.\n[Disconnect parent repo](command:codesync.disconnectRepo)\n[View Dashboard](command:codesync.viewDashboard)\n[Logout](command:codesync.logout)"
},
{
"view": "codesync-sub-dir-is-syncignored",
"contents": "Current directory is syncignored by a parent repo. To sync this directory, remove it from .syncignore.\n[Open .syncignore](command:codesync.openSyncIgnore)\n[View parent repo on web](command:codesync.trackRepo)\n[Disconnect parent repo](command:codesync.disconnectRepo)\n[View Dashboard](command:codesync.viewDashboard)\n[Logout](command:codesync.logout)"
"contents": "Current directory is syncignored by a parent repo. To sync this directory, remove it from .syncignore.\n[Open .syncignore](command:codesync.openSyncIgnore)\n[Disconnect parent repo](command:codesync.disconnectRepo)\n[View Dashboard](command:codesync.viewDashboard)\n[Logout](command:codesync.logout)"
},
{
"view": "codesync-is-loading",
Expand Down
2 changes: 1 addition & 1 deletion src/codesyncd/handlers/diff_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {generateSettings} from "../../settings";
import {readYML} from "../../utils/common";
import {CodeSyncLogger} from "../../logger";
import {pathUtils} from "../../utils/path_utils";
import {initUtils} from "../../init/utils";
import {initUtils} from "../../connect_repo/utils";
import {VSCODE} from "../../constants";
import { removeFile } from "../../utils/file_utils";

Expand Down
6 changes: 3 additions & 3 deletions src/codesyncd/populate_buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { glob } from 'glob';
import {isBinaryFileSync} from "isbinaryfile";
import stringSimilarity from "string-similarity";

import {initUtils} from "../init/utils";
import {initUtils} from "../connect_repo/utils";
import {IFileToUpload} from "../interface";
import {initHandler} from "../init/init_handler";
import {initHandler} from "../connect_repo/connect_repo_handler";
import {generateSettings} from "../settings";
import {pathUtils} from "../utils/path_utils";
import {
Expand Down Expand Up @@ -36,7 +36,7 @@ import {eventHandler} from "../events/event_handler";
import { CodeSyncLogger } from "../logger";
import { CODESYNC_STATES, CodeSyncState } from "../utils/state_utils";
import { removeFile } from "../utils/file_utils";
import { s3UploaderUtils } from "../init/s3_uploader";
import { s3UploaderUtils } from "../connect_repo/s3_uploader";
import { UserState } from "../utils/user_utils";


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import { initUtils } from './utils';
import { IUser } from '../interface';
import { pathUtils } from "../utils/path_utils";
import { askPublicPrivate } from '../utils/notifications';
import { askPersonalOrOrgRepo, askPublicPrivate } from '../utils/notifications';
import { isAccountActive } from '../utils/auth_utils';
import { checkServerDown } from "../utils/api_utils";
import { getBranch, readFile } from "../utils/common";
Expand Down Expand Up @@ -76,25 +76,24 @@

// Only ask for public/private in case of Repo Sync. Do not ask for Branch Sync.
if (this.viaDaemon) {
return await this.postPublicPrivate(user.email, false);
return await this.postOrgSelection(user.email, false);
}
// Open .syncignore and ask public/private info
const setting: vscode.Uri = vscode.Uri.parse("file:" + syncignorePath);
// Opening .syncignore
return await vscode.workspace.openTextDocument(setting).then(async (a: vscode.TextDocument) => {
return await vscode.window.showTextDocument(a, 1, false).then(async e => {
const buttonSelected = await askPublicPrivate(this.repoPath);
if (!buttonSelected) {
vscode.window.showWarningMessage(NOTIFICATION.INIT_CANCELLED);
const json = await askPersonalOrOrgRepo(this.accessToken, this.repoPath);

Check warning on line 86 in src/connect_repo/connect_repo_handler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
if (json.isCancelled) {
vscode.window.showWarningMessage(NOTIFICATION.CONNECT_REPO_CANCELLED);
return false;
}
const isPublic = buttonSelected == NOTIFICATION.PUBLIC;
return await this.postPublicPrivate(user.email, isPublic);
return await this.postOrgSelection(user.email, false, json.orgId, json.teamId);

Check warning on line 91 in src/connect_repo/connect_repo_handler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
});

Check warning on line 92 in src/connect_repo/connect_repo_handler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
});
};

postPublicPrivate = async (userEmail: string, isPublic: boolean) => {
postOrgSelection = async (userEmail: string, isPublic = false, orgId = null, teamId = null) => {

Check warning on line 96 in src/connect_repo/connect_repo_handler.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
CodeSyncState.set(CODESYNC_STATES.IS_SYNCING_BRANCH, new Date().getTime());
const initUtilsObj = new initUtils(this.repoPath, this.viaDaemon);
// get item paths to upload and copy in respective repos
Expand All @@ -108,7 +107,9 @@
const shadowRepoBranchPath = pathUtilsObj.getShadowRepoBranchPath();
initUtilsObj.copyFilesTo(filePaths, shadowRepoBranchPath);
// Upload repo/branch
const uploaded = await initUtilsObj.uploadRepo(this.branch, this.accessToken, itemPaths, userEmail, isPublic);
const uploaded = await initUtilsObj.uploadRepo(this.branch, this.accessToken,
itemPaths, userEmail, isPublic, null, orgId, teamId
);
return uploaded;
};
}
File renamed without changes.
21 changes: 9 additions & 12 deletions src/init/utils.ts → src/connect_repo/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { CONNECTION_ERROR_MESSAGE, VSCODE, NOTIFICATION, BRANCH_SYNC_TIMEOUT, co
import { getGlobIgnorePatterns, readYML, getSyncIgnoreItems, shouldIgnorePath, getDefaultIgnorePatterns } from '../utils/common';
import { CodeSyncState, CODESYNC_STATES } from '../utils/state_utils';
import { s3UploaderUtils } from './s3_uploader';
import { trackRepoHandler } from '../handlers/commands_handler';
import gitCommitInfo from 'git-commit-info';
import { RepoPlanLimitsState, RepoState } from '../utils/repo_state_utils';
import { captureTabs } from '../utils/tab_utils';
Expand Down Expand Up @@ -143,19 +142,13 @@ export class initUtils {
CodeSyncState.set(CODESYNC_STATES.IS_SYNCING_BRANCH, false);
// Hide Connect Repo
vscode.commands.executeCommand('setContext', contextVariables.showConnectRepoView, false);
if (this.viaDaemon) return;
// Show success notification
if (!this.viaDaemon) {
vscode.window.showInformationMessage(NOTIFICATION.REPO_CONNECTED, ...[
NOTIFICATION.TRACK_IT
]).then(selection => {
if (!selection) return;
if (selection === NOTIFICATION.TRACK_IT) return trackRepoHandler();
});
}
vscode.window.showInformationMessage(NOTIFICATION.REPO_CONNECTED);
}

async uploadRepo(branch: string, token: string, itemPaths: IFileToUpload[],
userEmail: string, isPublic=false, repoId=null) {
userEmail: string, isPublic=false, repoId=null, orgId=null, teamId=null) {
// Check plan limits
const repoLimitsState = new RepoPlanLimitsState(this.repoPath).get();
if (repoLimitsState.planLimitReached && !repoLimitsState.canRetry) return false;
Expand All @@ -176,7 +169,9 @@ export class initUtils {
if (!repoState.IS_CONNECTED) {
configJSON.repos[this.repoPath] = {
branches: {},
email: userEmail
email: userEmail,
orgId: orgId,
teamId: teamId
};
configJSON.repos[this.repoPath].branches[branch] = branchFiles;
fs.writeFileSync(this.settings.CONFIG_PATH, yaml.dump(configJSON));
Expand Down Expand Up @@ -212,7 +207,9 @@ export class initUtils {
commit_hash,
files_data: JSON.stringify(filesData),
source: VSCODE,
platform: os.platform()
platform: os.platform(),
org_id: configJSON.repos[this.repoPath].orgId,
team_id: configJSON.repos[this.repoPath].teamId
};

const json = await uploadRepoToServer(token, data, repoId);
Expand Down
10 changes: 7 additions & 3 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const apiRoutes = (): IApiRoutes => {
REPO_INIT: generateApiUrl("/init"),
REPOS: generateApiUrl(API_PATH.REPOS),
USERS: generateApiUrl("/users"),
USER_ORGANIZATIONS: generateApiUrl("/orgs"),
REACTIVATE_ACCOUNT: generateApiUrl("/users/reactivate"),
USER_SUBSCRIPTION: generateApiUrl("/users/subscription"),
DIFFS_WEBSOCKET: generateSocketUrl("/v2/websocket"),
Expand Down Expand Up @@ -69,7 +70,8 @@ export const NOTIFICATION_BUTTON = {
TRY_PRO_FOR_FREE: "Try Pro plan for free",
TRY_TEAM_FOR_FREE: "Try Team plan for free",
UPGRADE_TO_PRO: "Upgrade to Pro plan",
UPGRADE_TO_TEAM: "Upgrade to Team plan"
UPGRADE_TO_TEAM: "Upgrade to Team plan",
REPO_IS_PERSONAL: "Repo is personal"
};

// Notification Messages
Expand Down Expand Up @@ -107,7 +109,7 @@ export const NOTIFICATION = {
UPGRADE_ORG_PLAN: "Please upgrade your Organization's plan to continue using CodeSync",
UPGRADE_TO_PRO: "Upgrade to Pro plan",
TRY_PRO_FOR_FREE: "Try Pro plan for free",
INIT_CANCELLED: "Init process was cancelled",
CONNECT_REPO_CANCELLED: "'Connect Repo' process was cancelled",
NO_VALID_ACCOUNT: "No valid account found",
WAITING_FOR_LOGIN_CONFIRMATION: "Waiting for login confirmation from CodeSync...",
REPO_IN_SYNC: "is in sync with CodeSync.",
Expand All @@ -125,7 +127,9 @@ export const NOTIFICATION = {
SIGNUP_FAILED: "Sign up to CodeSync failed!",
ACCOUNT_DEACTIVATED: "Your account has been deactivated. Please click 'Reactivate Account' below to resume syncing.",
FREE_TIER_LIMIT_REACHED: "We hope you've found CodeSync useful. You'have hit the limit of Free tier for repo",
PRIVATE_REPO_COUNT_LIMIT_REACHED: "In the Free plan, you can have just one Private Repository"
PRIVATE_REPO_COUNT_LIMIT_REACHED: "In the Free plan, you can have just one Private Repository",
ASK_ORG_REPO: "Would you like to add this repository to any of the following organizations?",
ASK_TEAM_REPO: "Which team should this repository be added to?"
};

export const getRepoInSyncMsg = (repoPath: string) => {
Expand Down
2 changes: 1 addition & 1 deletion src/events/event_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import vscode from 'vscode';
import { globSync } from 'glob';

import { IDiff } from "../interface";
import { initUtils } from "../init/utils";
import { initUtils } from "../connect_repo/utils";
import { formatDatetime, getBranch, getDefaultIgnorePatterns, getSyncIgnoreItems, readFile, readYML, shouldIgnorePath } from "../utils/common";
import { generateSettings } from "../settings";
import { pathUtils } from "../utils/path_utils";
Expand Down
1 change: 1 addition & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export interface IApiRoutes {
REPO_INIT: string;
REPOS: string;
USERS: string;
USER_ORGANIZATIONS: string;
REACTIVATE_ACCOUNT: string;
USER_SUBSCRIPTION: string;
DIFFS_WEBSOCKET: string;
Expand Down
2 changes: 1 addition & 1 deletion src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
const userState = new UserState();
const activeUser = userState.getUser();
if (activeUser && activeUser.email !== userResponse.email) return res.send(msgs.TOKEN_VERIFICATION_FAILED);
postSuccessLogout();
await postSuccessLogout();

Check warning on line 61 in src/server/server.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
const redirectURL = generateWebUrl("", {type: "logout"});
// http://localhost:3000/?utm_medium=plugin&utm_source=vscode&type=logout
res.redirect(redirectURL);
Expand Down
3 changes: 3 additions & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import untildify from "untildify";
import { prodConfig } from "./config/prod";
import { stagingConfig } from "./config/staging";
import { devConfig } from "./config/dev";
import { formatDatetime } from "./utils/common";

// Set this to true for Development
const DEBUG = false;
Expand Down Expand Up @@ -70,8 +71,10 @@ export const generateSettings = () => {
*/
// System Directories for CodeSync
const rootRepo = untildify(systemConfig.ROOT_REPO);
const backupRepo = untildify(`${systemConfig.ROOT_REPO}-${formatDatetime()}`);
const systemDirectories = {
CODESYNC_ROOT: rootRepo,
BACKUP_ROOT: backupRepo,
DIFFS_REPO: path.join(rootRepo, ".diffs", ".vscode"),
TABS_PATH: path.join(rootRepo, ".tabs", ".vscode"),
ORIGINALS_REPO: path.join(rootRepo, ".originals"),
Expand Down
53 changes: 53 additions & 0 deletions src/utils/api_utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import fetch from "node-fetch";

import { apiRoutes } from "../constants";
import { generateApiUrl } from "./url_utils";


export const checkServerDown = async () => {
Expand Down Expand Up @@ -98,3 +99,55 @@ export const getUserSubcription = async (accessToken: string) => {
error
};
};


export const getRepoAvailableOrganizations = async (accessToken: string, repoName: string) => {
let error = "";
let orgs = <any>[];
const url = `${apiRoutes().USER_ORGANIZATIONS}&repo_name=${repoName}`;
const response = <any>await fetch(url, {
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${accessToken}`
}
})
.then(res => res.json())
.then(json => json)
.catch(err => error = err);
if (response.error) {
error = response.error.message;
} else {
orgs = response.orgs;
}

return {
orgs,
error
};
};

export const getOrgTeams = async (accessToken: string, orgId: number) => {
let error = "";
let teams = <any>[];
const orgTeamsUrl = generateApiUrl(`/orgs/${orgId}/teams`);
const response = <any>await fetch(
orgTeamsUrl, {
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${accessToken}`
}
})
.then(res => res.json())
.then(json => json)
.catch(err => error = err);
if (response.error) {
error = response.error.message;
} else {
teams = response.teams;
}

return {
teams,
error
};
};
28 changes: 18 additions & 10 deletions src/utils/auth_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
import {showConnectRepo} from "./notifications";
import {createUserWithApi} from "./api_utils";
import {generateSettings} from "../settings";
import {trackRepoHandler} from "../handlers/commands_handler";
import {contextVariables, ECONNREFUSED, getRepoInSyncMsg, HttpStatusCodes, NOTIFICATION, NOTIFICATION_BUTTON} from "../constants";
import { CodeSyncLogger } from "../logger";
import { pathUtils } from "./path_utils";
import { RepoState } from "./repo_state_utils";
import { UserState } from "./user_utils";
import { authHandler, reactivateAccountHandler } from "../handlers/user_commands";
import { createSystemDirectories, setupCodeSync } from "./setup_utils";


export const isPortAvailable = async (port: number) => {
Expand Down Expand Up @@ -63,14 +63,7 @@
return showConnectRepo(repoPath, userEmail, accessToken);
}
// Show notification that repo is in sync
vscode.window.showInformationMessage(getRepoInSyncMsg(repoPath), ...[
NOTIFICATION.TRACK_IT
]).then(selection => {
if (!selection) { return; }
if (selection === NOTIFICATION.TRACK_IT) {
trackRepoHandler();
}
});
vscode.window.showInformationMessage(getRepoInSyncMsg(repoPath));

Check warning on line 66 in src/utils/auth_utils.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
};

const postDeactivatedAccount = (userEmail: string, accessToken: string) => {
Expand Down Expand Up @@ -152,6 +145,19 @@
};


export const resetUserSession = async () => {
const settings = generateSettings();
try {
fs.renameSync(settings.CODESYNC_ROOT, settings.BACKUP_ROOT);
} catch (e) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
CodeSyncLogger.error("Failed to reset root repo", e.stack);
}
const repoPath = pathUtils.getRootPath();
await setupCodeSync(repoPath);
};

export const askAndTriggerSignUp = () => {
// Trigger sign up process
vscode.window.showErrorMessage(
Expand All @@ -169,8 +175,10 @@
return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
};

export const postSuccessLogout = () => {
export const postSuccessLogout = async () => {
markUsersInactive();
// Rename system directory
await resetUserSession();
if ((global as any).socketConnection) {
(global as any).socketConnection.close();
(global as any).socketConnection = null;
Expand Down
Loading
Loading