@mcp-z/oauth-google 1.0.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.
- package/LICENSE +21 -0
- package/README.md +93 -0
- package/dist/cjs/index.d.cts +16 -0
- package/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.js +112 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/lib/dcr-router.d.cts +44 -0
- package/dist/cjs/lib/dcr-router.d.ts +44 -0
- package/dist/cjs/lib/dcr-router.js +1189 -0
- package/dist/cjs/lib/dcr-router.js.map +1 -0
- package/dist/cjs/lib/dcr-utils.d.cts +160 -0
- package/dist/cjs/lib/dcr-utils.d.ts +160 -0
- package/dist/cjs/lib/dcr-utils.js +860 -0
- package/dist/cjs/lib/dcr-utils.js.map +1 -0
- package/dist/cjs/lib/dcr-verify.d.cts +53 -0
- package/dist/cjs/lib/dcr-verify.d.ts +53 -0
- package/dist/cjs/lib/dcr-verify.js +193 -0
- package/dist/cjs/lib/dcr-verify.js.map +1 -0
- package/dist/cjs/lib/fetch-with-timeout.d.cts +14 -0
- package/dist/cjs/lib/fetch-with-timeout.d.ts +14 -0
- package/dist/cjs/lib/fetch-with-timeout.js +257 -0
- package/dist/cjs/lib/fetch-with-timeout.js.map +1 -0
- package/dist/cjs/lib/token-verifier.d.cts +44 -0
- package/dist/cjs/lib/token-verifier.d.ts +44 -0
- package/dist/cjs/lib/token-verifier.js +253 -0
- package/dist/cjs/lib/token-verifier.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/providers/dcr.d.cts +107 -0
- package/dist/cjs/providers/dcr.d.ts +107 -0
- package/dist/cjs/providers/dcr.js +584 -0
- package/dist/cjs/providers/dcr.js.map +1 -0
- package/dist/cjs/providers/loopback-oauth.d.cts +119 -0
- package/dist/cjs/providers/loopback-oauth.d.ts +119 -0
- package/dist/cjs/providers/loopback-oauth.js +1334 -0
- package/dist/cjs/providers/loopback-oauth.js.map +1 -0
- package/dist/cjs/providers/service-account.d.cts +131 -0
- package/dist/cjs/providers/service-account.d.ts +131 -0
- package/dist/cjs/providers/service-account.js +800 -0
- package/dist/cjs/providers/service-account.js.map +1 -0
- package/dist/cjs/schemas/index.d.cts +20 -0
- package/dist/cjs/schemas/index.d.ts +20 -0
- package/dist/cjs/schemas/index.js +37 -0
- package/dist/cjs/schemas/index.js.map +1 -0
- package/dist/cjs/setup/config.d.cts +112 -0
- package/dist/cjs/setup/config.d.ts +112 -0
- package/dist/cjs/setup/config.js +236 -0
- package/dist/cjs/setup/config.js.map +1 -0
- package/dist/cjs/types.d.cts +173 -0
- package/dist/cjs/types.d.ts +173 -0
- package/dist/cjs/types.js +16 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/dcr-router.d.ts +44 -0
- package/dist/esm/lib/dcr-router.js +515 -0
- package/dist/esm/lib/dcr-router.js.map +1 -0
- package/dist/esm/lib/dcr-utils.d.ts +160 -0
- package/dist/esm/lib/dcr-utils.js +270 -0
- package/dist/esm/lib/dcr-utils.js.map +1 -0
- package/dist/esm/lib/dcr-verify.d.ts +53 -0
- package/dist/esm/lib/dcr-verify.js +53 -0
- package/dist/esm/lib/dcr-verify.js.map +1 -0
- package/dist/esm/lib/fetch-with-timeout.d.ts +14 -0
- package/dist/esm/lib/fetch-with-timeout.js +30 -0
- package/dist/esm/lib/fetch-with-timeout.js.map +1 -0
- package/dist/esm/lib/token-verifier.d.ts +44 -0
- package/dist/esm/lib/token-verifier.js +53 -0
- package/dist/esm/lib/token-verifier.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/providers/dcr.d.ts +107 -0
- package/dist/esm/providers/dcr.js +242 -0
- package/dist/esm/providers/dcr.js.map +1 -0
- package/dist/esm/providers/loopback-oauth.d.ts +119 -0
- package/dist/esm/providers/loopback-oauth.js +639 -0
- package/dist/esm/providers/loopback-oauth.js.map +1 -0
- package/dist/esm/providers/service-account.d.ts +131 -0
- package/dist/esm/providers/service-account.js +353 -0
- package/dist/esm/providers/service-account.js.map +1 -0
- package/dist/esm/schemas/index.d.ts +20 -0
- package/dist/esm/schemas/index.js +18 -0
- package/dist/esm/schemas/index.js.map +1 -0
- package/dist/esm/setup/config.d.ts +112 -0
- package/dist/esm/setup/config.js +258 -0
- package/dist/esm/setup/config.js.map +1 -0
- package/dist/esm/types.d.ts +173 -0
- package/dist/esm/types.js +6 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,800 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "ServiceAccountProvider", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return ServiceAccountProvider;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
var _fs = require("fs");
|
|
12
|
+
var _googleauthlibrary = require("google-auth-library");
|
|
13
|
+
var _jose = require("jose");
|
|
14
|
+
function _array_like_to_array(arr, len) {
|
|
15
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
16
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
17
|
+
return arr2;
|
|
18
|
+
}
|
|
19
|
+
function _array_without_holes(arr) {
|
|
20
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
21
|
+
}
|
|
22
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
23
|
+
try {
|
|
24
|
+
var info = gen[key](arg);
|
|
25
|
+
var value = info.value;
|
|
26
|
+
} catch (error) {
|
|
27
|
+
reject(error);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (info.done) {
|
|
31
|
+
resolve(value);
|
|
32
|
+
} else {
|
|
33
|
+
Promise.resolve(value).then(_next, _throw);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function _async_to_generator(fn) {
|
|
37
|
+
return function() {
|
|
38
|
+
var self = this, args = arguments;
|
|
39
|
+
return new Promise(function(resolve, reject) {
|
|
40
|
+
var gen = fn.apply(self, args);
|
|
41
|
+
function _next(value) {
|
|
42
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
43
|
+
}
|
|
44
|
+
function _throw(err) {
|
|
45
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
46
|
+
}
|
|
47
|
+
_next(undefined);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function _class_call_check(instance, Constructor) {
|
|
52
|
+
if (!(instance instanceof Constructor)) {
|
|
53
|
+
throw new TypeError("Cannot call a class as a function");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function _define_property(obj, key, value) {
|
|
57
|
+
if (key in obj) {
|
|
58
|
+
Object.defineProperty(obj, key, {
|
|
59
|
+
value: value,
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true,
|
|
62
|
+
writable: true
|
|
63
|
+
});
|
|
64
|
+
} else {
|
|
65
|
+
obj[key] = value;
|
|
66
|
+
}
|
|
67
|
+
return obj;
|
|
68
|
+
}
|
|
69
|
+
function _instanceof(left, right) {
|
|
70
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
71
|
+
return !!right[Symbol.hasInstance](left);
|
|
72
|
+
} else {
|
|
73
|
+
return left instanceof right;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function _iterable_to_array(iter) {
|
|
77
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
78
|
+
}
|
|
79
|
+
function _non_iterable_spread() {
|
|
80
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
81
|
+
}
|
|
82
|
+
function _object_spread(target) {
|
|
83
|
+
for(var i = 1; i < arguments.length; i++){
|
|
84
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
85
|
+
var ownKeys = Object.keys(source);
|
|
86
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
87
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
88
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
ownKeys.forEach(function(key) {
|
|
92
|
+
_define_property(target, key, source[key]);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return target;
|
|
96
|
+
}
|
|
97
|
+
function ownKeys(object, enumerableOnly) {
|
|
98
|
+
var keys = Object.keys(object);
|
|
99
|
+
if (Object.getOwnPropertySymbols) {
|
|
100
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
101
|
+
if (enumerableOnly) {
|
|
102
|
+
symbols = symbols.filter(function(sym) {
|
|
103
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
keys.push.apply(keys, symbols);
|
|
107
|
+
}
|
|
108
|
+
return keys;
|
|
109
|
+
}
|
|
110
|
+
function _object_spread_props(target, source) {
|
|
111
|
+
source = source != null ? source : {};
|
|
112
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
113
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
114
|
+
} else {
|
|
115
|
+
ownKeys(Object(source)).forEach(function(key) {
|
|
116
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return target;
|
|
120
|
+
}
|
|
121
|
+
function _to_consumable_array(arr) {
|
|
122
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
123
|
+
}
|
|
124
|
+
function _type_of(obj) {
|
|
125
|
+
"@swc/helpers - typeof";
|
|
126
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
127
|
+
}
|
|
128
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
129
|
+
if (!o) return;
|
|
130
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
131
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
132
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
133
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
134
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
135
|
+
}
|
|
136
|
+
function _ts_generator(thisArg, body) {
|
|
137
|
+
var f, y, t, _ = {
|
|
138
|
+
label: 0,
|
|
139
|
+
sent: function() {
|
|
140
|
+
if (t[0] & 1) throw t[1];
|
|
141
|
+
return t[1];
|
|
142
|
+
},
|
|
143
|
+
trys: [],
|
|
144
|
+
ops: []
|
|
145
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
146
|
+
return d(g, "next", {
|
|
147
|
+
value: verb(0)
|
|
148
|
+
}), d(g, "throw", {
|
|
149
|
+
value: verb(1)
|
|
150
|
+
}), d(g, "return", {
|
|
151
|
+
value: verb(2)
|
|
152
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
153
|
+
value: function() {
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
}), g;
|
|
157
|
+
function verb(n) {
|
|
158
|
+
return function(v) {
|
|
159
|
+
return step([
|
|
160
|
+
n,
|
|
161
|
+
v
|
|
162
|
+
]);
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function step(op) {
|
|
166
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
167
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
168
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
169
|
+
if (y = 0, t) op = [
|
|
170
|
+
op[0] & 2,
|
|
171
|
+
t.value
|
|
172
|
+
];
|
|
173
|
+
switch(op[0]){
|
|
174
|
+
case 0:
|
|
175
|
+
case 1:
|
|
176
|
+
t = op;
|
|
177
|
+
break;
|
|
178
|
+
case 4:
|
|
179
|
+
_.label++;
|
|
180
|
+
return {
|
|
181
|
+
value: op[1],
|
|
182
|
+
done: false
|
|
183
|
+
};
|
|
184
|
+
case 5:
|
|
185
|
+
_.label++;
|
|
186
|
+
y = op[1];
|
|
187
|
+
op = [
|
|
188
|
+
0
|
|
189
|
+
];
|
|
190
|
+
continue;
|
|
191
|
+
case 7:
|
|
192
|
+
op = _.ops.pop();
|
|
193
|
+
_.trys.pop();
|
|
194
|
+
continue;
|
|
195
|
+
default:
|
|
196
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
197
|
+
_ = 0;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
201
|
+
_.label = op[1];
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
205
|
+
_.label = t[1];
|
|
206
|
+
t = op;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
if (t && _.label < t[2]) {
|
|
210
|
+
_.label = t[2];
|
|
211
|
+
_.ops.push(op);
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
if (t[2]) _.ops.pop();
|
|
215
|
+
_.trys.pop();
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
op = body.call(thisArg, _);
|
|
219
|
+
} catch (e) {
|
|
220
|
+
op = [
|
|
221
|
+
6,
|
|
222
|
+
e
|
|
223
|
+
];
|
|
224
|
+
y = 0;
|
|
225
|
+
} finally{
|
|
226
|
+
f = t = 0;
|
|
227
|
+
}
|
|
228
|
+
if (op[0] & 5) throw op[1];
|
|
229
|
+
return {
|
|
230
|
+
value: op[0] ? op[1] : void 0,
|
|
231
|
+
done: true
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
var ServiceAccountProvider = /*#__PURE__*/ function() {
|
|
236
|
+
"use strict";
|
|
237
|
+
function ServiceAccountProvider(config) {
|
|
238
|
+
_class_call_check(this, ServiceAccountProvider);
|
|
239
|
+
this.config = config;
|
|
240
|
+
this.keyFilePath = config.keyFilePath;
|
|
241
|
+
this.scopes = config.scopes;
|
|
242
|
+
}
|
|
243
|
+
var _proto = ServiceAccountProvider.prototype;
|
|
244
|
+
/**
|
|
245
|
+
* Load and parse service account key file from disk
|
|
246
|
+
* Validates structure and caches for subsequent calls
|
|
247
|
+
*/ _proto.loadKeyFile = function loadKeyFile() {
|
|
248
|
+
return _async_to_generator(function() {
|
|
249
|
+
var fileContent, keyData, error;
|
|
250
|
+
return _ts_generator(this, function(_state) {
|
|
251
|
+
switch(_state.label){
|
|
252
|
+
case 0:
|
|
253
|
+
// Return cached key data if already loaded
|
|
254
|
+
if (this.keyData) {
|
|
255
|
+
return [
|
|
256
|
+
2,
|
|
257
|
+
this.keyData
|
|
258
|
+
];
|
|
259
|
+
}
|
|
260
|
+
_state.label = 1;
|
|
261
|
+
case 1:
|
|
262
|
+
_state.trys.push([
|
|
263
|
+
1,
|
|
264
|
+
3,
|
|
265
|
+
,
|
|
266
|
+
4
|
|
267
|
+
]);
|
|
268
|
+
return [
|
|
269
|
+
4,
|
|
270
|
+
_fs.promises.readFile(this.keyFilePath, 'utf-8')
|
|
271
|
+
];
|
|
272
|
+
case 2:
|
|
273
|
+
fileContent = _state.sent();
|
|
274
|
+
try {
|
|
275
|
+
keyData = JSON.parse(fileContent);
|
|
276
|
+
} catch (parseError) {
|
|
277
|
+
throw new Error("Failed to parse service account key file as JSON: ".concat(this.keyFilePath, "\n") + "Error: ".concat(_instanceof(parseError, Error) ? parseError.message : String(parseError)));
|
|
278
|
+
}
|
|
279
|
+
// Validate structure
|
|
280
|
+
this.keyData = this.validateKeyFile(keyData);
|
|
281
|
+
return [
|
|
282
|
+
2,
|
|
283
|
+
this.keyData
|
|
284
|
+
];
|
|
285
|
+
case 3:
|
|
286
|
+
error = _state.sent();
|
|
287
|
+
// Handle file not found
|
|
288
|
+
if (error.code === 'ENOENT') {
|
|
289
|
+
throw new Error("Service account key file not found: ".concat(this.keyFilePath, "\nMake sure GOOGLE_SERVICE_ACCOUNT_KEY_FILE points to a valid file path."));
|
|
290
|
+
}
|
|
291
|
+
// Handle permission errors
|
|
292
|
+
if (error.code === 'EACCES') {
|
|
293
|
+
throw new Error("Permission denied reading service account key file: ".concat(this.keyFilePath, "\nCheck file permissions (should be readable by current user)."));
|
|
294
|
+
}
|
|
295
|
+
// Re-throw other errors
|
|
296
|
+
throw error;
|
|
297
|
+
case 4:
|
|
298
|
+
return [
|
|
299
|
+
2
|
|
300
|
+
];
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}).call(this);
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Validate service account key file structure
|
|
307
|
+
* Ensures all required fields are present and correctly typed
|
|
308
|
+
*/ _proto.validateKeyFile = function validateKeyFile(data) {
|
|
309
|
+
if (!data || (typeof data === "undefined" ? "undefined" : _type_of(data)) !== 'object') {
|
|
310
|
+
throw new Error('Service account key file must contain a JSON object');
|
|
311
|
+
}
|
|
312
|
+
var obj = data;
|
|
313
|
+
// Validate type field
|
|
314
|
+
if (obj.type !== 'service_account') {
|
|
315
|
+
throw new Error('Invalid service account key file: Expected type "service_account", got "'.concat(obj.type, '"\nMake sure you downloaded a service account key, not an OAuth client credential.'));
|
|
316
|
+
}
|
|
317
|
+
// Validate required string fields
|
|
318
|
+
var requiredFields = [
|
|
319
|
+
'project_id',
|
|
320
|
+
'private_key_id',
|
|
321
|
+
'private_key',
|
|
322
|
+
'client_email',
|
|
323
|
+
'client_id',
|
|
324
|
+
'auth_uri',
|
|
325
|
+
'token_uri'
|
|
326
|
+
];
|
|
327
|
+
var missingFields = requiredFields.filter(function(field) {
|
|
328
|
+
return typeof obj[field] !== 'string' || !obj[field];
|
|
329
|
+
});
|
|
330
|
+
if (missingFields.length > 0) {
|
|
331
|
+
throw new Error("Service account key file is missing required fields: ".concat(missingFields.join(', '), "\nMake sure you downloaded a complete service account key file from Google Cloud Console."));
|
|
332
|
+
}
|
|
333
|
+
// Validate private key format
|
|
334
|
+
var privateKey = obj.private_key;
|
|
335
|
+
if (!privateKey.includes('BEGIN PRIVATE KEY') || !privateKey.includes('END PRIVATE KEY')) {
|
|
336
|
+
throw new Error('Service account private_key field does not contain a valid PEM-formatted key.\n' + 'Expected format: -----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----');
|
|
337
|
+
}
|
|
338
|
+
return obj;
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Generate signed JWT (JSON Web Token) for service account authentication
|
|
342
|
+
* Uses RS256 algorithm with private key from key file
|
|
343
|
+
*/ _proto.generateJWT = function generateJWT() {
|
|
344
|
+
return _async_to_generator(function() {
|
|
345
|
+
var keyData, privateKey, now, jwt;
|
|
346
|
+
return _ts_generator(this, function(_state) {
|
|
347
|
+
switch(_state.label){
|
|
348
|
+
case 0:
|
|
349
|
+
return [
|
|
350
|
+
4,
|
|
351
|
+
this.loadKeyFile()
|
|
352
|
+
];
|
|
353
|
+
case 1:
|
|
354
|
+
keyData = _state.sent();
|
|
355
|
+
return [
|
|
356
|
+
4,
|
|
357
|
+
(0, _jose.importPKCS8)(keyData.private_key, 'RS256')
|
|
358
|
+
];
|
|
359
|
+
case 2:
|
|
360
|
+
privateKey = _state.sent();
|
|
361
|
+
// Current time
|
|
362
|
+
now = Math.floor(Date.now() / 1000);
|
|
363
|
+
return [
|
|
364
|
+
4,
|
|
365
|
+
new _jose.SignJWT({
|
|
366
|
+
iss: keyData.client_email,
|
|
367
|
+
scope: this.scopes.join(' '),
|
|
368
|
+
aud: 'https://oauth2.googleapis.com/token',
|
|
369
|
+
exp: now + 3600,
|
|
370
|
+
iat: now
|
|
371
|
+
}).setProtectedHeader({
|
|
372
|
+
alg: 'RS256',
|
|
373
|
+
typ: 'JWT'
|
|
374
|
+
}).sign(privateKey)
|
|
375
|
+
];
|
|
376
|
+
case 3:
|
|
377
|
+
jwt = _state.sent();
|
|
378
|
+
return [
|
|
379
|
+
2,
|
|
380
|
+
jwt
|
|
381
|
+
];
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
}).call(this);
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* Exchange signed JWT for access token at Google OAuth endpoint
|
|
388
|
+
* POST to https://oauth2.googleapis.com/token with grant_type=jwt-bearer
|
|
389
|
+
*/ _proto.exchangeJWT = function exchangeJWT(jwt) {
|
|
390
|
+
return _async_to_generator(function() {
|
|
391
|
+
var tokenEndpoint, response, errorText, errorMessage, errorJson, tokenData, expiry, error;
|
|
392
|
+
return _ts_generator(this, function(_state) {
|
|
393
|
+
switch(_state.label){
|
|
394
|
+
case 0:
|
|
395
|
+
tokenEndpoint = 'https://oauth2.googleapis.com/token';
|
|
396
|
+
_state.label = 1;
|
|
397
|
+
case 1:
|
|
398
|
+
_state.trys.push([
|
|
399
|
+
1,
|
|
400
|
+
6,
|
|
401
|
+
,
|
|
402
|
+
7
|
|
403
|
+
]);
|
|
404
|
+
return [
|
|
405
|
+
4,
|
|
406
|
+
fetch(tokenEndpoint, {
|
|
407
|
+
method: 'POST',
|
|
408
|
+
headers: {
|
|
409
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
410
|
+
},
|
|
411
|
+
body: new URLSearchParams({
|
|
412
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
413
|
+
assertion: jwt
|
|
414
|
+
})
|
|
415
|
+
})
|
|
416
|
+
];
|
|
417
|
+
case 2:
|
|
418
|
+
response = _state.sent();
|
|
419
|
+
if (!!response.ok) return [
|
|
420
|
+
3,
|
|
421
|
+
4
|
|
422
|
+
];
|
|
423
|
+
return [
|
|
424
|
+
4,
|
|
425
|
+
response.text()
|
|
426
|
+
];
|
|
427
|
+
case 3:
|
|
428
|
+
errorText = _state.sent();
|
|
429
|
+
try {
|
|
430
|
+
errorJson = JSON.parse(errorText);
|
|
431
|
+
errorMessage = errorJson.error_description || errorJson.error || errorText;
|
|
432
|
+
} catch (unused) {
|
|
433
|
+
errorMessage = errorText;
|
|
434
|
+
}
|
|
435
|
+
// 400: Invalid JWT (malformed claims, expired, etc.)
|
|
436
|
+
if (response.status === 400) {
|
|
437
|
+
throw new Error("Invalid service account JWT: ".concat(errorMessage, "\nThis usually means the JWT claims are malformed or the key file is invalid."));
|
|
438
|
+
}
|
|
439
|
+
// 401: Unauthorized (revoked service account, wrong scopes, etc.)
|
|
440
|
+
if (response.status === 401) {
|
|
441
|
+
throw new Error("Service account authentication failed: ".concat(errorMessage, "\nThe service account may have been disabled or deleted. Check Google Cloud Console."));
|
|
442
|
+
}
|
|
443
|
+
// Other errors
|
|
444
|
+
throw new Error("Token exchange failed (HTTP ".concat(response.status, "): ").concat(errorMessage));
|
|
445
|
+
case 4:
|
|
446
|
+
return [
|
|
447
|
+
4,
|
|
448
|
+
response.json()
|
|
449
|
+
];
|
|
450
|
+
case 5:
|
|
451
|
+
tokenData = _state.sent();
|
|
452
|
+
// Calculate expiry timestamp (token expires in ~1 hour)
|
|
453
|
+
expiry = Date.now() + (tokenData.expires_in - 60) * 1000; // Subtract 60s for safety margin
|
|
454
|
+
return [
|
|
455
|
+
2,
|
|
456
|
+
{
|
|
457
|
+
token: tokenData.access_token,
|
|
458
|
+
expiry: expiry
|
|
459
|
+
}
|
|
460
|
+
];
|
|
461
|
+
case 6:
|
|
462
|
+
error = _state.sent();
|
|
463
|
+
// Network errors
|
|
464
|
+
if (_instanceof(error, TypeError) && error.message.includes('fetch')) {
|
|
465
|
+
throw new Error('Network error connecting to Google OAuth endpoint. Check internet connection.');
|
|
466
|
+
}
|
|
467
|
+
// Re-throw other errors
|
|
468
|
+
throw error;
|
|
469
|
+
case 7:
|
|
470
|
+
return [
|
|
471
|
+
2
|
|
472
|
+
];
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
})();
|
|
476
|
+
};
|
|
477
|
+
/**
|
|
478
|
+
* Get access token for Google APIs
|
|
479
|
+
* Generates fresh JWT and exchanges for access token on each call
|
|
480
|
+
*
|
|
481
|
+
* Note: accountId parameter is ignored for service accounts (service account is single static identity)
|
|
482
|
+
*/ _proto.getAccessToken = function getAccessToken(_accountId) {
|
|
483
|
+
return _async_to_generator(function() {
|
|
484
|
+
var jwt, _ref, token, expiry, error;
|
|
485
|
+
return _ts_generator(this, function(_state) {
|
|
486
|
+
switch(_state.label){
|
|
487
|
+
case 0:
|
|
488
|
+
// Check if we have a valid cached token (optional optimization)
|
|
489
|
+
if (this.cachedToken && this.cachedToken.expiry > Date.now()) {
|
|
490
|
+
return [
|
|
491
|
+
2,
|
|
492
|
+
this.cachedToken.token
|
|
493
|
+
];
|
|
494
|
+
}
|
|
495
|
+
_state.label = 1;
|
|
496
|
+
case 1:
|
|
497
|
+
_state.trys.push([
|
|
498
|
+
1,
|
|
499
|
+
4,
|
|
500
|
+
,
|
|
501
|
+
5
|
|
502
|
+
]);
|
|
503
|
+
return [
|
|
504
|
+
4,
|
|
505
|
+
this.generateJWT()
|
|
506
|
+
];
|
|
507
|
+
case 2:
|
|
508
|
+
jwt = _state.sent();
|
|
509
|
+
return [
|
|
510
|
+
4,
|
|
511
|
+
this.exchangeJWT(jwt)
|
|
512
|
+
];
|
|
513
|
+
case 3:
|
|
514
|
+
_ref = _state.sent(), token = _ref.token, expiry = _ref.expiry;
|
|
515
|
+
// Cache token for subsequent calls (optional optimization)
|
|
516
|
+
this.cachedToken = {
|
|
517
|
+
token: token,
|
|
518
|
+
expiry: expiry
|
|
519
|
+
};
|
|
520
|
+
return [
|
|
521
|
+
2,
|
|
522
|
+
token
|
|
523
|
+
];
|
|
524
|
+
case 4:
|
|
525
|
+
error = _state.sent();
|
|
526
|
+
// Add context to errors
|
|
527
|
+
throw new Error("Failed to get service account access token: ".concat(_instanceof(error, Error) ? error.message : String(error)));
|
|
528
|
+
case 5:
|
|
529
|
+
return [
|
|
530
|
+
2
|
|
531
|
+
];
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
}).call(this);
|
|
535
|
+
};
|
|
536
|
+
/**
|
|
537
|
+
* Get OAuth2Client with service account credentials for googleapis
|
|
538
|
+
* This is the CRITICAL method that servers use to get authenticated API clients
|
|
539
|
+
*
|
|
540
|
+
* Service account ONLY works with accountId='service-account' (single static identity)
|
|
541
|
+
*
|
|
542
|
+
@param accountId - Account identifier (must be 'service-account' or undefined)
|
|
543
|
+
* @returns OAuth2Client instance with access token credentials set
|
|
544
|
+
*/ _proto.toAuth = function toAuth(accountId) {
|
|
545
|
+
var _this = this;
|
|
546
|
+
var _this_config_logger;
|
|
547
|
+
// Service account ONLY works with 'service-account' account ID
|
|
548
|
+
if (accountId !== undefined && accountId !== 'service-account') {
|
|
549
|
+
throw new Error("ServiceAccountProvider only supports accountId='service-account', got '".concat(accountId, "'. Service account uses a single static identity pattern."));
|
|
550
|
+
}
|
|
551
|
+
// Create OAuth2Client instance (no client ID/secret needed for service accounts)
|
|
552
|
+
var client = new _googleauthlibrary.OAuth2Client();
|
|
553
|
+
// Override getRequestMetadataAsync to provide authentication headers for each request
|
|
554
|
+
// This is the method googleapis calls to get auth headers - can be async and fetch tokens on-demand
|
|
555
|
+
client.getRequestMetadataAsync = function(_url) {
|
|
556
|
+
return _async_to_generator(function() {
|
|
557
|
+
var token, headers, error, _this_config_logger;
|
|
558
|
+
return _ts_generator(this, function(_state) {
|
|
559
|
+
switch(_state.label){
|
|
560
|
+
case 0:
|
|
561
|
+
_state.trys.push([
|
|
562
|
+
0,
|
|
563
|
+
2,
|
|
564
|
+
,
|
|
565
|
+
3
|
|
566
|
+
]);
|
|
567
|
+
return [
|
|
568
|
+
4,
|
|
569
|
+
this.getAccessToken()
|
|
570
|
+
];
|
|
571
|
+
case 1:
|
|
572
|
+
token = _state.sent();
|
|
573
|
+
// Update client credentials for consistency (other googleapis methods might check these)
|
|
574
|
+
client.credentials = {
|
|
575
|
+
access_token: token,
|
|
576
|
+
token_type: 'Bearer'
|
|
577
|
+
};
|
|
578
|
+
// Return headers as Headers instance for proper TypeScript types
|
|
579
|
+
headers = new Headers();
|
|
580
|
+
headers.set('authorization', "Bearer ".concat(token));
|
|
581
|
+
return [
|
|
582
|
+
2,
|
|
583
|
+
{
|
|
584
|
+
headers: headers
|
|
585
|
+
}
|
|
586
|
+
];
|
|
587
|
+
case 2:
|
|
588
|
+
error = _state.sent();
|
|
589
|
+
(_this_config_logger = this.config.logger) === null || _this_config_logger === void 0 ? void 0 : _this_config_logger.error('Failed to get service account access token for API request', {
|
|
590
|
+
error: error
|
|
591
|
+
});
|
|
592
|
+
throw error;
|
|
593
|
+
case 3:
|
|
594
|
+
return [
|
|
595
|
+
2
|
|
596
|
+
];
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
}).call(_this);
|
|
600
|
+
};
|
|
601
|
+
// Override getAccessToken to support googleapis client API and direct token access
|
|
602
|
+
client.getAccessToken = function() {
|
|
603
|
+
return _async_to_generator(function() {
|
|
604
|
+
var token, error, _this_config_logger;
|
|
605
|
+
return _ts_generator(this, function(_state) {
|
|
606
|
+
switch(_state.label){
|
|
607
|
+
case 0:
|
|
608
|
+
_state.trys.push([
|
|
609
|
+
0,
|
|
610
|
+
2,
|
|
611
|
+
,
|
|
612
|
+
3
|
|
613
|
+
]);
|
|
614
|
+
return [
|
|
615
|
+
4,
|
|
616
|
+
this.getAccessToken()
|
|
617
|
+
];
|
|
618
|
+
case 1:
|
|
619
|
+
token = _state.sent();
|
|
620
|
+
return [
|
|
621
|
+
2,
|
|
622
|
+
{
|
|
623
|
+
token: token
|
|
624
|
+
}
|
|
625
|
+
];
|
|
626
|
+
case 2:
|
|
627
|
+
error = _state.sent();
|
|
628
|
+
(_this_config_logger = this.config.logger) === null || _this_config_logger === void 0 ? void 0 : _this_config_logger.error('Failed to get service account access token', {
|
|
629
|
+
error: error
|
|
630
|
+
});
|
|
631
|
+
throw error;
|
|
632
|
+
case 3:
|
|
633
|
+
return [
|
|
634
|
+
2
|
|
635
|
+
];
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
}).call(_this);
|
|
639
|
+
};
|
|
640
|
+
(_this_config_logger = this.config.logger) === null || _this_config_logger === void 0 ? void 0 : _this_config_logger.debug("ServiceAccountProvider: OAuth2Client created for ".concat(accountId));
|
|
641
|
+
return client;
|
|
642
|
+
};
|
|
643
|
+
/**
|
|
644
|
+
* Get service account email address
|
|
645
|
+
* Used for account registration and display
|
|
646
|
+
*
|
|
647
|
+
* Note: accountId parameter is ignored for service accounts
|
|
648
|
+
* @returns Service account email from key file (e.g., "service-account@project.iam.gserviceaccount.com")
|
|
649
|
+
*/ _proto.getUserEmail = function getUserEmail(_accountId) {
|
|
650
|
+
return _async_to_generator(function() {
|
|
651
|
+
var keyData;
|
|
652
|
+
return _ts_generator(this, function(_state) {
|
|
653
|
+
switch(_state.label){
|
|
654
|
+
case 0:
|
|
655
|
+
return [
|
|
656
|
+
4,
|
|
657
|
+
this.loadKeyFile()
|
|
658
|
+
];
|
|
659
|
+
case 1:
|
|
660
|
+
keyData = _state.sent();
|
|
661
|
+
return [
|
|
662
|
+
2,
|
|
663
|
+
keyData.client_email
|
|
664
|
+
];
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
}).call(this);
|
|
668
|
+
};
|
|
669
|
+
/**
|
|
670
|
+
* Create middleware wrapper for single-user authentication
|
|
671
|
+
* This is the CRITICAL method that integrates service account auth into MCP servers
|
|
672
|
+
*
|
|
673
|
+
* Middleware wraps tool, resource, and prompt handlers and injects authContext into extra parameter.
|
|
674
|
+
* Handlers receive OAuth2Client via extra.authContext.auth for API calls.
|
|
675
|
+
*
|
|
676
|
+
* @returns Object with withToolAuth, withResourceAuth, withPromptAuth methods
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```typescript
|
|
680
|
+
* // Server registration
|
|
681
|
+
* const authMiddleware = provider.authMiddleware();
|
|
682
|
+
* const tools = toolFactories.map(f => f()).map(authMiddleware.withToolAuth);
|
|
683
|
+
* const resources = resourceFactories.map(f => f()).map(authMiddleware.withResourceAuth);
|
|
684
|
+
* const prompts = promptFactories.map(f => f()).map(authMiddleware.withPromptAuth);
|
|
685
|
+
*
|
|
686
|
+
* // Tool handler receives auth
|
|
687
|
+
* async function handler({ id }: In, extra: EnrichedExtra) {
|
|
688
|
+
* // extra.authContext.auth is OAuth2Client (from middleware)
|
|
689
|
+
* const gmail = google.gmail({ version: 'v1', auth: extra.authContext.auth });
|
|
690
|
+
* }
|
|
691
|
+
* ```
|
|
692
|
+
*/ _proto.authMiddleware = function authMiddleware() {
|
|
693
|
+
var _this = this;
|
|
694
|
+
// Shared wrapper logic - extracts extra parameter from specified position
|
|
695
|
+
// Generic T captures the actual module type; handler is cast from unknown to callable
|
|
696
|
+
var wrapAtPosition = function(module, extraPosition) {
|
|
697
|
+
var _this1 = _this;
|
|
698
|
+
var originalHandler = module.handler;
|
|
699
|
+
var wrappedHandler = function() {
|
|
700
|
+
for(var _len = arguments.length, allArgs = new Array(_len), _key = 0; _key < _len; _key++){
|
|
701
|
+
allArgs[_key] = arguments[_key];
|
|
702
|
+
}
|
|
703
|
+
return _async_to_generator(function() {
|
|
704
|
+
var extra, accountId, serviceEmail, auth, error, message;
|
|
705
|
+
return _ts_generator(this, function(_state) {
|
|
706
|
+
switch(_state.label){
|
|
707
|
+
case 0:
|
|
708
|
+
// Extract extra from the correct position
|
|
709
|
+
extra = allArgs[extraPosition];
|
|
710
|
+
_state.label = 1;
|
|
711
|
+
case 1:
|
|
712
|
+
_state.trys.push([
|
|
713
|
+
1,
|
|
714
|
+
5,
|
|
715
|
+
,
|
|
716
|
+
6
|
|
717
|
+
]);
|
|
718
|
+
// Use fixed accountId for storage isolation (like device-code pattern)
|
|
719
|
+
accountId = 'service-account';
|
|
720
|
+
return [
|
|
721
|
+
4,
|
|
722
|
+
this.getUserEmail()
|
|
723
|
+
];
|
|
724
|
+
case 2:
|
|
725
|
+
serviceEmail = _state.sent();
|
|
726
|
+
// Get access token (generates JWT and exchanges if needed)
|
|
727
|
+
return [
|
|
728
|
+
4,
|
|
729
|
+
this.getAccessToken()
|
|
730
|
+
];
|
|
731
|
+
case 3:
|
|
732
|
+
_state.sent();
|
|
733
|
+
// Create OAuth2Client with service account credentials
|
|
734
|
+
auth = this.toAuth(accountId);
|
|
735
|
+
// Inject authContext and logger into extra parameter
|
|
736
|
+
extra.authContext = {
|
|
737
|
+
auth: auth,
|
|
738
|
+
accountId: accountId,
|
|
739
|
+
metadata: {
|
|
740
|
+
serviceEmail: serviceEmail
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
extra.logger = this.config.logger;
|
|
744
|
+
return [
|
|
745
|
+
4,
|
|
746
|
+
originalHandler.apply(void 0, _to_consumable_array(allArgs))
|
|
747
|
+
];
|
|
748
|
+
case 4:
|
|
749
|
+
// Call original handler with all args
|
|
750
|
+
return [
|
|
751
|
+
2,
|
|
752
|
+
_state.sent()
|
|
753
|
+
];
|
|
754
|
+
case 5:
|
|
755
|
+
error = _state.sent();
|
|
756
|
+
message = _instanceof(error, Error) ? error.message : String(error);
|
|
757
|
+
// Provide specific, actionable error messages based on error type
|
|
758
|
+
if (message.includes('key file not found')) {
|
|
759
|
+
throw new Error("Service account setup error: Key file '".concat(this.keyFilePath, "' not found.\n• Set GOOGLE_SERVICE_ACCOUNT_KEY_FILE environment variable\n• Or ensure the file path exists and is accessible"));
|
|
760
|
+
}
|
|
761
|
+
if (message.includes('Forbidden') || message.includes('access_denied')) {
|
|
762
|
+
throw new Error('Service account permission error: The service account does not have required permissions.\n' + '• Ensure the service account has been granted the necessary roles\n' + '• Check that required API scopes are enabled in Google Cloud Console\n' + '• Verify the service account is active (not disabled)');
|
|
763
|
+
}
|
|
764
|
+
if (message.includes('invalid_grant') || message.includes('JWT')) {
|
|
765
|
+
throw new Error('Service account authentication error: Invalid credentials or expired tokens.\n' + '• Verify your service account key file is valid and not expired\n' + '• Check that the service account email and project match your GCP setup\n' + '• Try regenerating the key file in Google Cloud Console');
|
|
766
|
+
}
|
|
767
|
+
if (message.includes('Network error') || message.includes('fetch')) {
|
|
768
|
+
throw new Error('Service account connection error: Unable to reach Google authentication services.\n' + '• Check your internet connection\n' + '• Verify firewall/proxy settings allow HTTPS to oauth2.googleapis.com\n' + '• Try again in a few moments (may be temporary service issue)');
|
|
769
|
+
}
|
|
770
|
+
// Generic fallback with original error
|
|
771
|
+
throw new Error("Service account authentication failed: ".concat(message));
|
|
772
|
+
case 6:
|
|
773
|
+
return [
|
|
774
|
+
2
|
|
775
|
+
];
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
}).call(_this1);
|
|
779
|
+
};
|
|
780
|
+
return _object_spread_props(_object_spread({}, module), {
|
|
781
|
+
handler: wrappedHandler
|
|
782
|
+
});
|
|
783
|
+
};
|
|
784
|
+
return {
|
|
785
|
+
// Use structural constraints to avoid contravariance check on handler type.
|
|
786
|
+
// wrapAtPosition is now generic and returns T directly.
|
|
787
|
+
withToolAuth: function(module) {
|
|
788
|
+
return wrapAtPosition(module, 1);
|
|
789
|
+
},
|
|
790
|
+
withResourceAuth: function(module) {
|
|
791
|
+
return wrapAtPosition(module, 2);
|
|
792
|
+
},
|
|
793
|
+
withPromptAuth: function(module) {
|
|
794
|
+
return wrapAtPosition(module, 0);
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
};
|
|
798
|
+
return ServiceAccountProvider;
|
|
799
|
+
}();
|
|
800
|
+
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
|