@manojkmfsi/monodog 1.1.21 → 1.1.23
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.
- package/CHANGELOG.md +12 -0
- package/dist/controllers/publish-controller.js +311 -0
- package/dist/middleware/auth-middleware.js +27 -4
- package/dist/middleware/server-startup.js +9 -0
- package/dist/routes/auth-routes.js +30 -2
- package/dist/routes/publish-routes.js +46 -0
- package/dist/services/changeset-service.js +249 -0
- package/dist/utils/utilities.js +49 -0
- package/monodog-dashboard/dist/assets/index-7G3SCgcz.css +1 -0
- package/monodog-dashboard/dist/assets/index-BMoE990p.js +13 -0
- package/monodog-dashboard/dist/assets/index-BMoE990p.js.map +1 -0
- package/monodog-dashboard/dist/index.html +2 -2
- package/package.json +1 -1
- package/monodog-dashboard/dist/assets/index-DN0rk9Ub.css +0 -1
- package/monodog-dashboard/dist/assets/index-DS89XTlx.js +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @manojkmfsi/monoapp
|
|
2
2
|
|
|
3
|
+
## 1.1.23
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`b90aa90`](https://github.com/manojkmfsi/monodog/commit/b90aa90bfbf516128af033c883a21ca4d09f713d) - dcdsdsvdvdvxvcxvxvx
|
|
8
|
+
|
|
9
|
+
## 1.1.22
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`6015ae6`](https://github.com/manojkmfsi/monodog/commit/6015ae608b6b89061ab5cc1dd633d974d2a5ac27) - ddfdfdfdvdvcv
|
|
14
|
+
|
|
3
15
|
## 1.1.21
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPublishPackages = getPublishPackages;
|
|
4
|
+
exports.getPublishChangesets = getPublishChangesets;
|
|
5
|
+
exports.previewPublish = previewPublish;
|
|
6
|
+
exports.createChangeset = createChangeset;
|
|
7
|
+
exports.checkPublishStatus = checkPublishStatus;
|
|
8
|
+
exports.triggerPublish = triggerPublish;
|
|
9
|
+
const logger_1 = require("../middleware/logger");
|
|
10
|
+
const auth_middleware_1 = require("../middleware/auth-middleware");
|
|
11
|
+
const changeset_service_1 = require("../services/changeset-service");
|
|
12
|
+
/**
|
|
13
|
+
* Get all workspace packages
|
|
14
|
+
*/
|
|
15
|
+
async function getPublishPackages(req, res) {
|
|
16
|
+
try {
|
|
17
|
+
const rootPath = req.app.locals.rootPath;
|
|
18
|
+
const packages = await (0, changeset_service_1.getWorkspacePackages)(rootPath);
|
|
19
|
+
// Filter out private packages for UI display
|
|
20
|
+
const publicPackages = packages.filter((pkg) => !pkg.private);
|
|
21
|
+
res.json({
|
|
22
|
+
success: true,
|
|
23
|
+
packages: publicPackages,
|
|
24
|
+
total: publicPackages.length,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
logger_1.AppLogger.error(`Failed to fetch packages: ${error}`);
|
|
29
|
+
res.status(500).json({
|
|
30
|
+
success: false,
|
|
31
|
+
error: 'Failed to fetch packages',
|
|
32
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get existing unpublished changesets
|
|
38
|
+
*/
|
|
39
|
+
async function getPublishChangesets(req, res) {
|
|
40
|
+
try {
|
|
41
|
+
const rootPath = req.app.locals.rootPath;
|
|
42
|
+
const changesets = await (0, changeset_service_1.getExistingChangesets)(rootPath);
|
|
43
|
+
res.json({
|
|
44
|
+
success: true,
|
|
45
|
+
changesets,
|
|
46
|
+
total: changesets.length,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
logger_1.AppLogger.error(`Failed to fetch changesets: ${error}`);
|
|
51
|
+
res.status(500).json({
|
|
52
|
+
success: false,
|
|
53
|
+
error: 'Failed to fetch changesets',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Preview publish plan (calculate new versions, affected packages)
|
|
59
|
+
*/
|
|
60
|
+
async function previewPublish(req, res) {
|
|
61
|
+
try {
|
|
62
|
+
const { packages: selectedPackageNames, bumps } = req.body;
|
|
63
|
+
if (!selectedPackageNames || !Array.isArray(selectedPackageNames)) {
|
|
64
|
+
res.status(400).json({
|
|
65
|
+
success: false,
|
|
66
|
+
error: 'Invalid request',
|
|
67
|
+
message: 'packages array is required',
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const rootPath = req.app.locals.rootPath;
|
|
72
|
+
const allPackages = await (0, changeset_service_1.getWorkspacePackages)(rootPath);
|
|
73
|
+
// Filter selected packages
|
|
74
|
+
const selectedPackages = allPackages.filter((pkg) => selectedPackageNames.includes(pkg.name));
|
|
75
|
+
// Calculate new versions
|
|
76
|
+
const newVersions = (0, changeset_service_1.calculateNewVersions)(selectedPackages, bumps || []);
|
|
77
|
+
// Check if working tree is clean
|
|
78
|
+
const isClean = true; //await isWorkingTreeClean(rootPath);
|
|
79
|
+
// Get existing changesets
|
|
80
|
+
const changesets = await (0, changeset_service_1.getExistingChangesets)(rootPath);
|
|
81
|
+
// Perform validation checks
|
|
82
|
+
const errors = [];
|
|
83
|
+
const warnings = [];
|
|
84
|
+
// Get authenticated user
|
|
85
|
+
const session = (0, auth_middleware_1.getSessionFromRequest)(req);
|
|
86
|
+
const authUser = req.user;
|
|
87
|
+
const userPermission = req.permission.permission || 'read';
|
|
88
|
+
// Check 1: Working tree clean
|
|
89
|
+
const workingTreeClean = isClean;
|
|
90
|
+
if (!workingTreeClean) {
|
|
91
|
+
errors.push('Working tree has uncommitted changes');
|
|
92
|
+
}
|
|
93
|
+
// Check 2: User permissions
|
|
94
|
+
const permissionHierarchy = {
|
|
95
|
+
admin: 4,
|
|
96
|
+
maintain: 3,
|
|
97
|
+
write: 2,
|
|
98
|
+
read: 1,
|
|
99
|
+
none: 0,
|
|
100
|
+
};
|
|
101
|
+
const userLevel = permissionHierarchy[userPermission] || 0;
|
|
102
|
+
const requiredLevel = permissionHierarchy['write'] || 0;
|
|
103
|
+
const permissions = userLevel >= requiredLevel;
|
|
104
|
+
if (!permissions) {
|
|
105
|
+
errors.push(`Insufficient permissions. Required: write, Got: ${userPermission}`);
|
|
106
|
+
}
|
|
107
|
+
// Check 3: CI passing (simplified - always true for now)
|
|
108
|
+
const ciPassing = true;
|
|
109
|
+
// Check 4: Version available on npm (simplified - always true for now)
|
|
110
|
+
const versionAvailable = true;
|
|
111
|
+
logger_1.AppLogger.info(`Publishing preview for user: ${authUser?.login} (permission: ${userPermission})`);
|
|
112
|
+
const isValid = errors.length === 0;
|
|
113
|
+
res.json({
|
|
114
|
+
success: true,
|
|
115
|
+
isValid,
|
|
116
|
+
errors,
|
|
117
|
+
warnings,
|
|
118
|
+
checks: {
|
|
119
|
+
permissions,
|
|
120
|
+
workingTreeClean,
|
|
121
|
+
ciPassing,
|
|
122
|
+
versionAvailable,
|
|
123
|
+
},
|
|
124
|
+
preview: {
|
|
125
|
+
packages: newVersions,
|
|
126
|
+
workingTreeClean: isClean,
|
|
127
|
+
existingChangesets: changesets.length,
|
|
128
|
+
affectedPackages: newVersions.length,
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
logger_1.AppLogger.error(`Failed to preview publish: ${error}`);
|
|
134
|
+
res.status(500).json({
|
|
135
|
+
success: false,
|
|
136
|
+
error: 'Failed to preview publish',
|
|
137
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Create a new changeset
|
|
143
|
+
*/
|
|
144
|
+
async function createChangeset(req, res) {
|
|
145
|
+
try {
|
|
146
|
+
const { packages: selectedPackageNames, bumps, summary } = req.body;
|
|
147
|
+
const authUser = req.user;
|
|
148
|
+
const userPermission = req.permission.permission || 'read';
|
|
149
|
+
if (!selectedPackageNames || !Array.isArray(selectedPackageNames)) {
|
|
150
|
+
res.status(400).json({
|
|
151
|
+
success: false,
|
|
152
|
+
error: 'Invalid request',
|
|
153
|
+
message: 'packages array is required',
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (!summary || typeof summary !== 'string' || summary.length < 10) {
|
|
158
|
+
res.status(400).json({
|
|
159
|
+
success: false,
|
|
160
|
+
error: 'Invalid summary',
|
|
161
|
+
message: 'Summary must be at least 10 characters',
|
|
162
|
+
});
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Check permissions
|
|
166
|
+
const permissionHierarchy = {
|
|
167
|
+
admin: 4,
|
|
168
|
+
maintain: 3,
|
|
169
|
+
write: 2,
|
|
170
|
+
read: 1,
|
|
171
|
+
none: 0,
|
|
172
|
+
};
|
|
173
|
+
const userLevel = permissionHierarchy[userPermission] || 0;
|
|
174
|
+
const requiredLevel = permissionHierarchy['write'] || 0;
|
|
175
|
+
if (userLevel < requiredLevel) {
|
|
176
|
+
logger_1.AppLogger.warn(`User ${authUser?.login} attempted to create changeset without write permission`);
|
|
177
|
+
res.status(403).json({
|
|
178
|
+
success: false,
|
|
179
|
+
error: 'Forbidden',
|
|
180
|
+
message: `This action requires write permission. You have: ${userPermission}`,
|
|
181
|
+
});
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const rootPath = req.app.locals.rootPath;
|
|
185
|
+
logger_1.AppLogger.info(`Creating changeset for user: ${authUser?.login} (permission: ${userPermission})`);
|
|
186
|
+
// Generate the changeset
|
|
187
|
+
const result = await (0, changeset_service_1.generateChangeset)(rootPath, selectedPackageNames, bumps || [], summary, authUser?.login);
|
|
188
|
+
if (!result.success) {
|
|
189
|
+
res.status(400).json({
|
|
190
|
+
success: false,
|
|
191
|
+
error: 'Failed to create changeset',
|
|
192
|
+
message: result.message,
|
|
193
|
+
});
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
res.json({
|
|
197
|
+
success: true,
|
|
198
|
+
changeset: result.changeset,
|
|
199
|
+
message: 'Changeset created successfully',
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
logger_1.AppLogger.error(`Failed to create changeset: ${error}`);
|
|
204
|
+
res.status(500).json({
|
|
205
|
+
success: false,
|
|
206
|
+
error: 'Failed to create changeset',
|
|
207
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Check publish readiness
|
|
213
|
+
*/
|
|
214
|
+
async function checkPublishStatus(req, res) {
|
|
215
|
+
try {
|
|
216
|
+
const rootPath = req.app.locals.rootPath;
|
|
217
|
+
// Check if working tree is clean
|
|
218
|
+
const isClean = true; //await isWorkingTreeClean(rootPath);
|
|
219
|
+
// Get existing changesets
|
|
220
|
+
const changesets = await (0, changeset_service_1.getExistingChangesets)(rootPath);
|
|
221
|
+
res.json({
|
|
222
|
+
success: true,
|
|
223
|
+
status: {
|
|
224
|
+
workingTreeClean: isClean,
|
|
225
|
+
hasChangesets: changesets.length > 0,
|
|
226
|
+
changesetCount: changesets.length,
|
|
227
|
+
readyToPublish: isClean && changesets.length > 0,
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
logger_1.AppLogger.error(`Failed to check publish status: ${error}`);
|
|
233
|
+
res.status(500).json({
|
|
234
|
+
success: false,
|
|
235
|
+
error: 'Failed to check publish status',
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Trigger publishing workflow
|
|
241
|
+
*/
|
|
242
|
+
async function triggerPublish(req, res) {
|
|
243
|
+
try {
|
|
244
|
+
const rootPath = req.app.locals.rootPath;
|
|
245
|
+
const authUser = req.user;
|
|
246
|
+
const userPermission = req.permission.permission || 'read';
|
|
247
|
+
// Check permissions
|
|
248
|
+
const permissionHierarchy = {
|
|
249
|
+
admin: 4,
|
|
250
|
+
maintain: 3,
|
|
251
|
+
write: 2,
|
|
252
|
+
read: 1,
|
|
253
|
+
none: 0,
|
|
254
|
+
};
|
|
255
|
+
const userLevel = permissionHierarchy[userPermission] || 0;
|
|
256
|
+
const requiredLevel = permissionHierarchy['maintain'] || 0;
|
|
257
|
+
if (userLevel < requiredLevel) {
|
|
258
|
+
logger_1.AppLogger.warn(`User ${authUser?.login} attempted to trigger publish without maintain permission`);
|
|
259
|
+
res.status(403).json({
|
|
260
|
+
success: false,
|
|
261
|
+
error: 'Forbidden',
|
|
262
|
+
message: `This action requires maintain permission. You have: ${userPermission}`,
|
|
263
|
+
});
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
// Check if working tree is clean
|
|
267
|
+
const isClean = true; //await isWorkingTreeClean(rootPath);
|
|
268
|
+
if (!isClean) {
|
|
269
|
+
res.status(400).json({
|
|
270
|
+
success: false,
|
|
271
|
+
error: 'Working tree not clean',
|
|
272
|
+
message: 'Please commit or stash all changes before publishing',
|
|
273
|
+
});
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
// Check if changesets exist
|
|
277
|
+
const changesets = await (0, changeset_service_1.getExistingChangesets)(rootPath);
|
|
278
|
+
if (changesets.length === 0) {
|
|
279
|
+
res.status(400).json({
|
|
280
|
+
success: false,
|
|
281
|
+
error: 'No changesets found',
|
|
282
|
+
message: 'Create changesets before publishing',
|
|
283
|
+
});
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
logger_1.AppLogger.info(`Triggering publish for user: ${authUser?.login} (permission: ${userPermission})`);
|
|
287
|
+
// Trigger publish pipeline with user context
|
|
288
|
+
const result = await (0, changeset_service_1.triggerPublishPipeline)(rootPath, authUser?.login);
|
|
289
|
+
if (!result.success) {
|
|
290
|
+
res.status(500).json({
|
|
291
|
+
success: false,
|
|
292
|
+
error: 'Failed to trigger publish pipeline',
|
|
293
|
+
message: result.message,
|
|
294
|
+
});
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
res.json({
|
|
298
|
+
success: true,
|
|
299
|
+
message: 'Publishing workflow initiated',
|
|
300
|
+
result: result.result,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
logger_1.AppLogger.error(`Failed to trigger publish: ${error}`);
|
|
305
|
+
res.status(500).json({
|
|
306
|
+
success: false,
|
|
307
|
+
error: 'Failed to trigger publish',
|
|
308
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -90,9 +90,30 @@ function authenticationMiddleware(req, res, next) {
|
|
|
90
90
|
});
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
|
-
// Attach session to request
|
|
93
|
+
// Attach session and user info to request
|
|
94
94
|
req.session = session;
|
|
95
|
-
|
|
95
|
+
req.user = {
|
|
96
|
+
login: session.user.login,
|
|
97
|
+
id: session.user.id,
|
|
98
|
+
};
|
|
99
|
+
// Attach permission from session (if available)
|
|
100
|
+
if (session.permission) {
|
|
101
|
+
req.permission = session.permission;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Default to 'read' if no permission fetched
|
|
105
|
+
req.permission = {
|
|
106
|
+
permission: 'read',
|
|
107
|
+
role: 'Denied',
|
|
108
|
+
userId: session.user.id,
|
|
109
|
+
username: session.user.login,
|
|
110
|
+
owner: '',
|
|
111
|
+
repo: '',
|
|
112
|
+
cachedAt: Date.now(),
|
|
113
|
+
ttl: 0,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
logger_1.AppLogger.debug(`Authenticated request from user: ${session.user.login} with permission: ${req.permission?.permission || 'unknown'}`);
|
|
96
117
|
next();
|
|
97
118
|
}
|
|
98
119
|
/**
|
|
@@ -124,10 +145,12 @@ function repositoryPermissionMiddleware(requiredPermission) {
|
|
|
124
145
|
read: 1,
|
|
125
146
|
none: 0,
|
|
126
147
|
};
|
|
127
|
-
|
|
148
|
+
// Handle both string and object formats for permission
|
|
149
|
+
const userPermissionString = typeof permission === 'string' ? permission : (permission.permission || 'none');
|
|
150
|
+
const userLevel = permissionHierarchy[userPermissionString] || 0;
|
|
128
151
|
const requiredLevel = permissionHierarchy[requiredPermission] || 0;
|
|
129
152
|
if (userLevel < requiredLevel) {
|
|
130
|
-
logger_1.AppLogger.warn(`User ${session.user.login} lacks permission for action requiring ${requiredPermission}`);
|
|
153
|
+
logger_1.AppLogger.warn(`User ${session.user.login} lacks permission for action requiring ${requiredPermission} (has ${userPermissionString})`);
|
|
131
154
|
res.status(403).json({
|
|
132
155
|
error: 'Forbidden',
|
|
133
156
|
message: `This action requires ${requiredPermission} permission`,
|
|
@@ -20,6 +20,7 @@ const health_routes_1 = __importDefault(require("../routes/health-routes"));
|
|
|
20
20
|
const config_routes_1 = __importDefault(require("../routes/config-routes"));
|
|
21
21
|
const auth_routes_1 = __importDefault(require("../routes/auth-routes"));
|
|
22
22
|
const permission_routes_1 = __importDefault(require("../routes/permission-routes"));
|
|
23
|
+
const publish_routes_1 = __importDefault(require("../routes/publish-routes"));
|
|
23
24
|
const constants_1 = require("../constants");
|
|
24
25
|
const auth_middleware_1 = require("./auth-middleware");
|
|
25
26
|
const permission_service_1 = require("../services/permission-service");
|
|
@@ -64,6 +65,7 @@ function createApp(rootPath) {
|
|
|
64
65
|
app.use('/api/commits/', commit_routes_1.default);
|
|
65
66
|
app.use('/api/health/', health_routes_1.default);
|
|
66
67
|
app.use('/api/config/', config_routes_1.default);
|
|
68
|
+
app.use('/api/publish', publish_routes_1.default);
|
|
67
69
|
// 404 handler
|
|
68
70
|
app.use('*', error_handler_1.notFoundHandler);
|
|
69
71
|
// Global error handler (must be last)
|
|
@@ -109,6 +111,13 @@ function startServer(rootPath) {
|
|
|
109
111
|
// Config endpoints
|
|
110
112
|
'PUT /api/config/files/:id',
|
|
111
113
|
'GET /api/config/files',
|
|
114
|
+
// Publish endpoints
|
|
115
|
+
'GET /api/publish/packages',
|
|
116
|
+
'GET /api/publish/changesets',
|
|
117
|
+
'GET /api/publish/status',
|
|
118
|
+
'POST /api/publish/preview',
|
|
119
|
+
'POST /api/publish/changesets',
|
|
120
|
+
'POST /api/publish/trigger',
|
|
112
121
|
],
|
|
113
122
|
});
|
|
114
123
|
});
|
|
@@ -7,7 +7,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const express_1 = require("express");
|
|
8
8
|
const github_oauth_service_1 = require("../services/github-oauth-service");
|
|
9
9
|
const auth_middleware_1 = require("../middleware/auth-middleware");
|
|
10
|
+
const permission_service_1 = require("../services/permission-service");
|
|
10
11
|
const logger_1 = require("../middleware/logger");
|
|
12
|
+
const utilities_1 = require("../utils/utilities");
|
|
11
13
|
const router = (0, express_1.Router)();
|
|
12
14
|
// OAuth configuration (should come from environment variables)
|
|
13
15
|
// const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID || '';
|
|
@@ -138,13 +140,34 @@ router.get('/callback', async (req, res) => {
|
|
|
138
140
|
// Get user information
|
|
139
141
|
logger_1.AppLogger.debug('Retrieving authenticated user information');
|
|
140
142
|
const user = await (0, github_oauth_service_1.getAuthenticatedUser)(tokenResponse.access_token);
|
|
141
|
-
//
|
|
143
|
+
// Fetch user's repository permission
|
|
144
|
+
let permission = null;
|
|
145
|
+
try {
|
|
146
|
+
logger_1.AppLogger.debug(`Fetching repository permission for user ${user.login}`);
|
|
147
|
+
// Extract repository info from git remote
|
|
148
|
+
const repoInfo = await (0, utilities_1.getRepositoryInfoFromGit)();
|
|
149
|
+
if (!repoInfo) {
|
|
150
|
+
logger_1.AppLogger.warn('Could not extract repository info from git remote - permission fetch skipped');
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
const { owner, repo } = repoInfo;
|
|
154
|
+
permission = await (0, permission_service_1.getUserRepositoryPermission)(tokenResponse.access_token, user.id, user.login, owner, repo);
|
|
155
|
+
logger_1.AppLogger.info(`User ${user.login} has ${permission.permission} permission on ${owner}/${repo}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (permError) {
|
|
159
|
+
logger_1.AppLogger.error(`Failed to fetch repository permission: ${permError}`);
|
|
160
|
+
// Continue without permission - will be checked on protected routes
|
|
161
|
+
permission = null;
|
|
162
|
+
}
|
|
163
|
+
// Create session with permission
|
|
142
164
|
const session = {
|
|
143
165
|
accessToken: tokenResponse.access_token,
|
|
144
166
|
expiresIn: 3600, // 1 hour default
|
|
145
167
|
expiresAt: Date.now() + 24 * 60 * 60 * 1000, // 24 hours
|
|
146
168
|
user,
|
|
147
169
|
scopes: tokenResponse.scope.split(','),
|
|
170
|
+
permission, // Include fetched permission in session
|
|
148
171
|
};
|
|
149
172
|
// Store session and get token
|
|
150
173
|
const sessionToken = (0, auth_middleware_1.storeSession)(session);
|
|
@@ -152,7 +175,7 @@ router.get('/callback', async (req, res) => {
|
|
|
152
175
|
const redirectUrl = getRedirectUrl(state) || '/';
|
|
153
176
|
// Clear state
|
|
154
177
|
clearState(state);
|
|
155
|
-
logger_1.AppLogger.info(`User authenticated: ${user.login}`);
|
|
178
|
+
logger_1.AppLogger.info(`User authenticated: ${user.login} with permission: ${permission?.permission || 'unknown'}`);
|
|
156
179
|
res.json({
|
|
157
180
|
success: true,
|
|
158
181
|
message: 'Authentication successful',
|
|
@@ -164,6 +187,10 @@ router.get('/callback', async (req, res) => {
|
|
|
164
187
|
name: user.name,
|
|
165
188
|
avatar_url: user.avatar_url,
|
|
166
189
|
},
|
|
190
|
+
permission: permission ? {
|
|
191
|
+
level: permission.permission,
|
|
192
|
+
role: permission.role,
|
|
193
|
+
} : null,
|
|
167
194
|
});
|
|
168
195
|
}
|
|
169
196
|
catch (error) {
|
|
@@ -203,6 +230,7 @@ router.get('/me', auth_middleware_1.authenticationMiddleware, (req, res) => {
|
|
|
203
230
|
},
|
|
204
231
|
scopes: session.scopes,
|
|
205
232
|
expiresAt: session.expiresAt,
|
|
233
|
+
permission: session.permission || null,
|
|
206
234
|
});
|
|
207
235
|
}
|
|
208
236
|
catch (error) {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const express_1 = __importDefault(require("express"));
|
|
7
|
+
const publish_controller_1 = require("../controllers/publish-controller");
|
|
8
|
+
const auth_middleware_1 = require("../middleware/auth-middleware");
|
|
9
|
+
const publishRouter = express_1.default.Router();
|
|
10
|
+
/**
|
|
11
|
+
* GET /api/publish/packages
|
|
12
|
+
* Get all workspace packages for publishing
|
|
13
|
+
* Requires: read permission
|
|
14
|
+
*/
|
|
15
|
+
publishRouter.get('/packages', auth_middleware_1.authenticationMiddleware, publish_controller_1.getPublishPackages);
|
|
16
|
+
/**
|
|
17
|
+
* GET /api/publish/changesets
|
|
18
|
+
* Get existing unpublished changesets
|
|
19
|
+
* Requires: read permission
|
|
20
|
+
*/
|
|
21
|
+
publishRouter.get('/changesets', auth_middleware_1.authenticationMiddleware, publish_controller_1.getPublishChangesets);
|
|
22
|
+
/**
|
|
23
|
+
* POST /api/publish/preview
|
|
24
|
+
* Preview the publish plan (calculate new versions, affected packages)
|
|
25
|
+
* Requires: read permission
|
|
26
|
+
*/
|
|
27
|
+
publishRouter.post('/preview', auth_middleware_1.authenticationMiddleware, publish_controller_1.previewPublish);
|
|
28
|
+
/**
|
|
29
|
+
* POST /api/publish/changesets
|
|
30
|
+
* Create a new changeset for the selected packages
|
|
31
|
+
* Requires: write permission
|
|
32
|
+
*/
|
|
33
|
+
publishRouter.post('/changesets', auth_middleware_1.authenticationMiddleware, (0, auth_middleware_1.repositoryPermissionMiddleware)('write'), publish_controller_1.createChangeset);
|
|
34
|
+
/**
|
|
35
|
+
* GET /api/publish/status
|
|
36
|
+
* Check publish readiness (working tree, changesets, etc.)
|
|
37
|
+
* Requires: read permission
|
|
38
|
+
*/
|
|
39
|
+
publishRouter.get('/status', auth_middleware_1.authenticationMiddleware, publish_controller_1.checkPublishStatus);
|
|
40
|
+
/**
|
|
41
|
+
* POST /api/publish/trigger
|
|
42
|
+
* Trigger the publishing workflow
|
|
43
|
+
* Requires: maintain permission
|
|
44
|
+
*/
|
|
45
|
+
publishRouter.post('/trigger', auth_middleware_1.authenticationMiddleware, (0, auth_middleware_1.repositoryPermissionMiddleware)('maintain'), publish_controller_1.triggerPublish);
|
|
46
|
+
exports.default = publishRouter;
|