Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
b57e8d9
Ai documentation
Nuri1977 Oct 22, 2025
9e34e10
Iplemented depplink authentication with Cloud Nextjs App
Nuri1977 Oct 23, 2025
101cdba
feat(profile): add Cloud Dashboard profile integration
Nuri1977 Oct 27, 2025
baee54b
remove AI documents
Nuri1977 Oct 27, 2025
dfa54aa
update gitignore
Nuri1977 Oct 27, 2025
feb393c
Merge branch 'dev' into feature/authentication
jasir99 Oct 28, 2025
5ff0b23
minor fixes
jasir99 Oct 28, 2025
eccbe51
refactored the service class
jasir99 Oct 29, 2025
55967b7
fixed commit issues
jasir99 Oct 29, 2025
c884ee3
completed refactoring and added env support in settings
jasir99 Oct 29, 2025
2b82f31
fixed eslint errors
jasir99 Oct 29, 2025
89eb6b1
run project if already pushed
jasir99 Oct 29, 2025
d34820e
added support to push secrets
jasir99 Oct 29, 2025
98cf574
Update Push to Cloud Modal to check if project is already deployed
Nuri1977 Oct 29, 2025
be0f86f
Merge branch 'feature/authentication' of github.com:rosettadb/dbt-stu…
Nuri1977 Oct 29, 2025
1d70844
removed unnecessary code
jasir99 Oct 29, 2025
c84ca83
added git check messages before deploying to cloud
jasir99 Oct 29, 2025
d8ab06b
design fixes
jasir99 Oct 29, 2025
3120f44
dropped api key support
jasir99 Oct 30, 2025
f3a662e
Implemented a swith for local/cloud enviroment variable
Nuri1977 Oct 30, 2025
91e5d5e
added git checks
jasir99 Oct 30, 2025
380a7df
added support to render secrets
jasir99 Oct 30, 2025
b6faf5d
fixed errors
jasir99 Oct 30, 2025
2753380
fixed errors
jasir99 Oct 30, 2025
0356fef
fixed url
jasir99 Oct 30, 2025
4cb9b3b
fixed env loading
jasir99 Oct 30, 2025
8fd419e
Make cloud workspace URL read-only with production URL
Nuri1977 Oct 31, 2025
7ada032
use api key instead of token
jasir99 Nov 5, 2025
1f7558b
Replace auth token with Api_key for Rosetta Cloud auth
Nuri1977 Nov 6, 2025
e3dc677
Merge branch 'feature/authentication' of github.com:rosettadb/dbt-stu…
Nuri1977 Nov 6, 2025
3575248
revert CLOUD_DASHBOARD_API_KEY constant
Nuri1977 Nov 6, 2025
1322cc8
added support for updates when running a pipeline
jasir99 Nov 7, 2025
a68ee5d
version bump: 1.2.3
jasir99 Nov 7, 2025
37b529e
fixed dbt command keys
jasir99 Nov 7, 2025
d8d3f3b
fixed command composition
jasir99 Nov 7, 2025
e5db2d0
Change rosetta cloud ligin button and UI auth flow
Nuri1977 Nov 10, 2025
cb12716
Merge branch 'feature/authentication' of github.com:rosettadb/dbt-stu…
Nuri1977 Nov 10, 2025
fea88a0
Change "Sign in" text with "Connect"
Nuri1977 Nov 10, 2025
ee954b4
feat: add environment-aware command filtering and cloud execution sup…
Nuri1977 Nov 10, 2025
b29c230
Add dashboard Link to Menu
Nuri1977 Nov 14, 2025
28bb8d0
Merge branch 'refs/heads/dev' into feature/authentication
jasir99 Nov 27, 2025
dc487ca
version bump 1.2.4
jasir99 Nov 27, 2025
a0ecad0
Merge branch 'refs/heads/dev' into feature/authentication
jasir99 Nov 27, 2025
29c96c8
fixed button
jasir99 Nov 27, 2025
0e8430b
Merge branch 'dev' into feature/authentication
jasir99 Dec 16, 2025
ae0286f
Merge branch 'dev' into feature/authentication
jasir99 Dec 25, 2025
f079aab
merged latest dev
jasir99 Dec 25, 2025
0aeb7c3
Merge branch 'dev' into feature/authentication
jasir99 Jan 8, 2026
ea38c39
Merge branch 'dev' into feature/authentication
jasir99 Jan 13, 2026
737596f
version bump: 1.2.7
jasir99 Jan 13, 2026
78bf8d2
Change icon of the cloud dashboard in main Menu
Nuri1977 Jan 23, 2026
d56dbec
Merge branch 'dev' into feature/authentication
jasir99 Jan 23, 2026
fd907b6
Merge branch 'dev' into feature/authentication
jasir99 Feb 4, 2026
9ca5901
version bump for internal testing release with authentication enabled
jasir99 Feb 4, 2026
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
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches:
- main
- release/dev
- feature/authentication
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove feature branch from publish triggers before merging.

Adding a feature branch to the publish workflow will create draft releases from unfinished code. This appears to be a temporary addition for testing purposes. Ensure this line is removed before merging to dev to avoid:

  • Orphan draft releases from the feature branch
  • Unnecessary CI/CD resource consumption (macOS runners, code signing)
  • Potential release tag conflicts if the version matches an existing release
🤖 Prompt for AI Agents
In @.github/workflows/publish.yml at line 8, Remove the temporary feature branch
entry "feature/authentication" from the publish workflow triggers: edit the
publish.yml workflow's push/branches array and delete the
"feature/authentication" entry so the workflow only triggers on the intended
branches (e.g., dev/main); ensure no leftover references to that branch remain
before merging.


env:
# This will be set by the first job and used by all others
Expand Down
3 changes: 2 additions & 1 deletion assets/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logo from './logo.svg';
import { icons } from './icons';
import rosettaIcon from './icon.png';

export { logo, icons };
export { logo, icons, rosettaIcon };
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.3.0",
"version": "1.3.1-auth-internal",
"name": "rosetta-dbt-studio",
"description": "Turn Raw Data into Business Insights—Faster with RosettaDB",
"keywords": [
Expand Down
4 changes: 2 additions & 2 deletions release/app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion release/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rosetta-dbt-studio",
"version": "1.3.0",
"version": "1.3.1-auth-internal",
"description": "A modern DBT desktop IDE",
"license": "MIT",
"author": {
Expand Down
27 changes: 26 additions & 1 deletion src/main/ipcHandlers/git.ipcHandlers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { ipcMain } from 'electron';
import { GitService } from '../services';
import { AuthError } from '../errors';
import { FileStatus, GitCredentials } from '../../types/backend';
import {
FileStatus,
GitChangesRes,
GitCredentials,
RepoInfoRes,
} from '../../types/backend';

const gitService = new GitService();

Expand Down Expand Up @@ -206,6 +211,26 @@ const registerGitHandlers = () => {
},
);

ipcMain.handle(
'git:getLocalChanges',
async (
_event,
{ repoPath }: { repoPath: string },
): Promise<GitChangesRes | null> => {
return gitService.getLocalChangesStatus(repoPath);
},
);

ipcMain.handle(
'git:repoInfo',
async (
_event,
{ repoPath }: { repoPath: string },
): Promise<RepoInfoRes | null> => {
return gitService.getRepoInfo(repoPath);
},
);

ipcMain.handle(
'git:unstage',
async (
Expand Down
2 changes: 2 additions & 0 deletions src/main/ipcHandlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import registerSecureStorageHandlers from './secureStorage.ipcHandlers';
import registerUpdateHandlers from './updates.ipcHandlers';
import registerCloudExplorerHandlers from './cloudExplorer.ipcHandlers';
import registerAIHandlers from './ai.ipcHandlers';
import registerRosettaCloudIpcHandlers from './rosettaCloud.ipcHandlers';
import registerDuckLakeHandlers from './duckLake.ipcHandlers';
import registerLineageHandlers from './lineage.ipcHandlers';

Expand All @@ -24,6 +25,7 @@ export {
registerUpdateHandlers,
registerCloudExplorerHandlers,
registerAIHandlers,
registerRosettaCloudIpcHandlers,
registerDuckLakeHandlers,
registerLineageHandlers,
};
17 changes: 0 additions & 17 deletions src/main/ipcHandlers/projects.ipcHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,23 +207,6 @@ const registerProjectHandlers = () => {
return ProjectsService.downloadSeed(body);
},
);

ipcMain.handle(
'project:pushToCloud',
async (
_event,
body: {
title: string;
gitUrl: string;
gitBranch: string;
apiKey: string;
githubUsername?: string;
githubPassword?: string;
},
) => {
return ProjectsService.pushProjectToCloud(body);
},
);
};

export default registerProjectHandlers;
63 changes: 63 additions & 0 deletions src/main/ipcHandlers/rosettaCloud.ipcHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { ipcMain } from 'electron';
import { RosettaCloudService } from '../services';
import { CloudDeploymentPayload } from '../../types/backend';

const registerRosettaCloudIpcHandlers = () => {
ipcMain.handle(
'rosettaCloud:push',
async (_event, body: CloudDeploymentPayload) => {
return RosettaCloudService.pushProjectToCloud(body);
},
);

ipcMain.handle('rosettaCloud:getProfile', async () => {
return RosettaCloudService.getProfile();
});

ipcMain.handle('rosettaCloud:refreshProfile', async () => {
return RosettaCloudService.refreshProfile();
});

ipcMain.handle('rosettaCloud:getCachedProfile', async () => {
return RosettaCloudService.getCachedProfile();
});

ipcMain.handle('rosettaCloud:login', async () => {
return RosettaCloudService.openLogin();
});

ipcMain.handle('rosettaCloud:getApiKey', async () => {
return RosettaCloudService.getApiKey();
});

ipcMain.handle('rosettaCloud:logout', async () => {
await RosettaCloudService.clearApiKey();
});

ipcMain.handle('rosettaCloud:storeApiKey', async (_event, apiKey: string) => {
await RosettaCloudService.storeApiKey(apiKey);
});

ipcMain.handle(
'rosettaCloud:validateApiKey',
async (_event, apiKey: string) => {
return RosettaCloudService.validateApiKey(apiKey);
},
);

ipcMain.handle(
'rosettaCloud:getSecrets',
async (_event, projectId: string) => {
return RosettaCloudService.getSecrets(projectId);
},
);

ipcMain.handle(
'rosettaCloud:deleteSecret',
async (_event, projectId: string, secretId: string) => {
return RosettaCloudService.deleteSecret(projectId, secretId);
},
);
};

export default registerRosettaCloudIpcHandlers;
2 changes: 2 additions & 0 deletions src/main/ipcSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
registerUpdateHandlers,
registerCloudExplorerHandlers,
registerAIHandlers,
registerRosettaCloudIpcHandlers,
registerDuckLakeHandlers,
registerLineageHandlers,
} from './ipcHandlers';
Expand All @@ -27,6 +28,7 @@ const registerHandlers = (mainWindow: BrowserWindow) => {
registerUpdateHandlers();
registerCloudExplorerHandlers();
registerAIHandlers();
registerRosettaCloudIpcHandlers();
registerDuckLakeHandlers();
registerLineageHandlers();
};
Expand Down
98 changes: 96 additions & 2 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
SettingsService,
AnalyticsService,
UpdateService,
RosettaCloudService,
DuckLakeConnectionManager,
} from './services';
import { copyAssetsToUserData } from './utils/fileHelper';
Expand All @@ -31,13 +32,85 @@ protocol.registerSchemesAsPrivileged([
bypassCSP: true,
},
},
{
scheme: 'rosetta',
privileges: {
standard: true,
secure: true,
},
},
]);

setupApplicationIcon();

let windowManager: WindowManager | null = null;
async function handleDeepLink(url: string) {
try {
const parsedUrl = new URL(url);
if (
parsedUrl.protocol === 'rosetta:' &&
(parsedUrl.pathname === '//auth' || parsedUrl.host === 'auth')
) {
const apiKey = parsedUrl.searchParams.get('token'); // Still called 'token' in URL for compatibility
if (apiKey) {
try {
await RosettaCloudService.storeApiKey(apiKey);

windowManager
?.getMainWindow()
?.webContents.send('rosettaCloud:apiKeyUpdated');

windowManager
?.getMainWindow()
?.webContents.send('rosettaCloud:authSuccess', {
apiKey,
});

return;
} catch (storageError) {
console.error(
'Failed to store API key from deep link:',
storageError,
);
windowManager
?.getMainWindow()
?.webContents.send('rosettaCloud:authError', {
error: 'Failed to store API key. Please try again.',
});
return;
}
}

windowManager
?.getMainWindow()
?.webContents.send('rosettaCloud:authError', {
error: 'Missing API key in deep link response.',
});
}
} catch (error) {
console.error('Deep link processing error:', error);
windowManager?.getMainWindow()?.webContents.send('rosettaCloud:authError', {
error:
error instanceof Error
? `Failed to process deep link: ${error.message}`
: 'Failed to process deep link.',
});
}
}

// Ensure single instance of the app
const gotTheLock = app.requestSingleInstanceLock();
let windowManager: WindowManager | null = null;

// Register custom protocol for deep linking
if (process.defaultApp) {
if (process.argv.length >= 2) {
app.setAsDefaultProtocolClient('rosetta', process.execPath, [
process.argv[1],
]);
}
} else {
app.setAsDefaultProtocolClient('rosetta');
}

if (!gotTheLock) {
console.log('Another instance is already running. Quitting...');
Expand Down Expand Up @@ -150,9 +223,15 @@ if (!gotTheLock) {
})
.catch(console.log);

app.on('second-instance', () => {
app.on('second-instance', (event, commandLine) => {
if (!windowManager) return;

// Handle deep link from second instance
const url = commandLine.find((arg) => arg.startsWith('rosetta://'));
if (url) {
handleDeepLink(url);
}

const activeWindow = windowManager.getMainWindow();

if (activeWindow) {
Expand All @@ -163,6 +242,21 @@ if (!gotTheLock) {
windowManager.startApplication();
}
});

// Handle deep links on macOS
app.on('open-url', (event, url) => {
event.preventDefault();
handleDeepLink(url);
});

// Handle deep links on Windows/Linux
app.on('ready', () => {
// Check if app was opened with a deep link
const url = process.argv.find((arg) => arg.startsWith('rosetta://'));
if (url) {
handleDeepLink(url);
}
});
Comment on lines +252 to +259
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Deep links on cold start may be silently lost.

When the app is launched via a deep link on Windows/Linux, this ready handler fires before windowManager and the main window are created (lines 119-190). The optional chaining prevents crashes, but the rosettaCloud:authSuccess notification will be silently dropped.

Consider deferring deep link handling until the main window is ready, or queuing the URL for later processing.

🔎 Proposed approach
+let pendingDeepLinkUrl: string | null = null;
+
 async function handleDeepLink(url: string) {
+  // If main window not ready, queue the URL
+  if (!windowManager?.getMainWindow()) {
+    pendingDeepLinkUrl = url;
+    return;
+  }
   try {
     // ... existing logic
   }
 }

 // In the splash.webContents.once('did-finish-load') callback, after showMainWindow():
+if (pendingDeepLinkUrl) {
+  handleDeepLink(pendingDeepLinkUrl);
+  pendingDeepLinkUrl = null;
+}

Committable suggestion skipped: line range outside the PR's diff.

}

ipcMain.handle('windows:closeSetup', () => {
Expand Down
Loading