@marcoappio/marco-config 4.0.2 → 4.0.3
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.
|
@@ -263,7 +263,7 @@ declare const rowSchemas: {
|
|
|
263
263
|
readonly operation: v.PicklistSchema<readonly ["CONNECT", "REPLACE"], undefined>;
|
|
264
264
|
readonly profile: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
265
265
|
readonly provider: v.PicklistSchema<readonly ["GMAIL", "OUTLOOK"], undefined>;
|
|
266
|
-
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/
|
|
266
|
+
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/loading"], undefined>;
|
|
267
267
|
readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
268
268
|
readonly $createdAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
269
269
|
readonly $databaseId: v.LiteralSchema<"marco", undefined>;
|
|
@@ -481,8 +481,8 @@ export declare const appwrite: {
|
|
|
481
481
|
readonly oauth: {
|
|
482
482
|
readonly operations: readonly ["CONNECT", "REPLACE"];
|
|
483
483
|
readonly providers: readonly ["GMAIL", "OUTLOOK"];
|
|
484
|
-
readonly returnUriSchema: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/
|
|
485
|
-
readonly returnUris: readonly ["https://app.marcoapp.io/onboarding/
|
|
484
|
+
readonly returnUriSchema: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/loading"], undefined>;
|
|
485
|
+
readonly returnUris: readonly ["https://app.marcoapp.io/onboarding/loading"];
|
|
486
486
|
};
|
|
487
487
|
readonly polling: {
|
|
488
488
|
readonly shardStates: readonly ["ACTIVE", "STOPPED", "FAILED"];
|
|
@@ -710,7 +710,7 @@ export declare const appwrite: {
|
|
|
710
710
|
readonly operation: v.PicklistSchema<readonly ["CONNECT", "REPLACE"], undefined>;
|
|
711
711
|
readonly profile: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
712
712
|
readonly provider: v.PicklistSchema<readonly ["GMAIL", "OUTLOOK"], undefined>;
|
|
713
|
-
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/
|
|
713
|
+
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/loading"], undefined>;
|
|
714
714
|
readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 255, undefined>]>;
|
|
715
715
|
readonly $createdAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
|
|
716
716
|
readonly $databaseId: v.LiteralSchema<"marco", undefined>;
|
|
@@ -48,7 +48,7 @@ const mailboxSyncLaneStates = ['PENDING', 'RUNNING', 'COMPLETED', 'FAILED'];
|
|
|
48
48
|
const mailboxSyncStates = ['INITIAL', 'SYNCING', 'CURRENT', 'ERROR'];
|
|
49
49
|
const oauthOperations = ['CONNECT', 'REPLACE'];
|
|
50
50
|
const oauthProviders = ['GMAIL', 'OUTLOOK'];
|
|
51
|
-
const oauthReturnUris = ['https://app.marcoapp.io/onboarding/
|
|
51
|
+
const oauthReturnUris = ['https://app.marcoapp.io/onboarding/loading'];
|
|
52
52
|
const oauthReturnUriSchema = v.picklist(oauthReturnUris);
|
|
53
53
|
const pollShardStates = ['ACTIVE', 'STOPPED', 'FAILED'];
|
|
54
54
|
const appwriteEnvironments = ['development', 'production', 'staging'];
|
|
@@ -180,7 +180,7 @@ const validRows = {
|
|
|
180
180
|
operation: 'CONNECT',
|
|
181
181
|
profile: 'user-1',
|
|
182
182
|
provider: 'GMAIL',
|
|
183
|
-
returnUri: 'https://app.marcoapp.io/onboarding/
|
|
183
|
+
returnUri: 'https://app.marcoapp.io/onboarding/loading',
|
|
184
184
|
userId: 'user-1',
|
|
185
185
|
},
|
|
186
186
|
pollShards: {
|
|
@@ -326,9 +326,24 @@ describe('appwrite', () => {
|
|
|
326
326
|
expect(appwrite.oauth).toMatchObject({
|
|
327
327
|
operations: ['CONNECT', 'REPLACE'],
|
|
328
328
|
providers: ['GMAIL', 'OUTLOOK'],
|
|
329
|
-
returnUris: ['https://app.marcoapp.io/onboarding/
|
|
329
|
+
returnUris: ['https://app.marcoapp.io/onboarding/loading'],
|
|
330
330
|
});
|
|
331
331
|
});
|
|
332
|
+
for (const operation of ['CONNECT', 'REPLACE']) {
|
|
333
|
+
it(`accepts a persisted ${operation} OAuth state completing at production loading`, () => {
|
|
334
|
+
expect(v.safeParse(appwrite.rowSchemas.oauthStates, { ...validRows.oauthStates, operation }).success).toBe(true);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
for (const returnUri of [
|
|
338
|
+
'https://app.marcoapp.io/onboarding/provider-selection',
|
|
339
|
+
'https://app.staging.marcoapp.io/onboarding/loading',
|
|
340
|
+
'https://attacker.example/onboarding/loading',
|
|
341
|
+
'https://app.marcoapp.io/onboarding/loading/unexpected',
|
|
342
|
+
]) {
|
|
343
|
+
it(`rejects persisted OAuth state with unapproved return URI ${returnUri}`, () => {
|
|
344
|
+
expect(v.safeParse(appwrite.rowSchemas.oauthStates, { ...validRows.oauthStates, returnUri }).success).toBe(false);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
332
347
|
it('exports the final polling-only mailbox contract', () => {
|
|
333
348
|
expect(appwrite.mailboxSync).toEqual({
|
|
334
349
|
laneStates: ['PENDING', 'RUNNING', 'COMPLETED', 'FAILED'],
|
|
@@ -18,7 +18,7 @@ export declare const appwriteFunctions: {
|
|
|
18
18
|
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
|
|
19
19
|
readonly kind: v.LiteralSchema<"OAUTH", undefined>;
|
|
20
20
|
readonly provider: v.PicklistSchema<["GMAIL", "OUTLOOK"], undefined>;
|
|
21
|
-
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/
|
|
21
|
+
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/loading"], undefined>;
|
|
22
22
|
}, undefined>, v.StrictObjectSchema<{
|
|
23
23
|
readonly imap: v.StrictObjectSchema<{
|
|
24
24
|
readonly host: v.NonOptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>, v.MaxLengthAction<string, number, undefined>]>, undefined>;
|
|
@@ -69,7 +69,7 @@ export declare const appwriteFunctions: {
|
|
|
69
69
|
readonly email: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
|
|
70
70
|
readonly kind: v.LiteralSchema<"OAUTH", undefined>;
|
|
71
71
|
readonly provider: v.PicklistSchema<["GMAIL", "OUTLOOK"], undefined>;
|
|
72
|
-
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/
|
|
72
|
+
readonly returnUri: v.PicklistSchema<readonly ["https://app.marcoapp.io/onboarding/loading"], undefined>;
|
|
73
73
|
}, undefined>, v.StrictObjectSchema<{
|
|
74
74
|
readonly imap: v.StrictObjectSchema<{
|
|
75
75
|
readonly host: v.NonOptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.NonEmptyAction<string, undefined>, v.MaxLengthAction<string, number, undefined>]>, undefined>;
|
|
@@ -54,7 +54,7 @@ const routeFixtures = [
|
|
|
54
54
|
email: 'test-user@example.com',
|
|
55
55
|
kind: 'OAUTH',
|
|
56
56
|
provider: 'GMAIL',
|
|
57
|
-
returnUri: 'https://app.marcoapp.io/onboarding/
|
|
57
|
+
returnUri: 'https://app.marcoapp.io/onboarding/loading',
|
|
58
58
|
},
|
|
59
59
|
},
|
|
60
60
|
response: {
|
|
@@ -314,16 +314,12 @@ describe('appwriteFunctions', () => {
|
|
|
314
314
|
description: 'a malformed mailbox email',
|
|
315
315
|
expected: false,
|
|
316
316
|
},
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
},
|
|
324
|
-
description: 'an unapproved return destination',
|
|
325
|
-
expected: false,
|
|
326
|
-
},
|
|
317
|
+
];
|
|
318
|
+
const forbiddenOAuthReturnUris = [
|
|
319
|
+
{ description: 'provider-selection', returnUri: 'https://app.marcoapp.io/onboarding/provider-selection' },
|
|
320
|
+
{ description: 'staging loading', returnUri: 'https://app.staging.marcoapp.io/onboarding/loading' },
|
|
321
|
+
{ description: 'arbitrary origin', returnUri: 'https://attacker.example/onboarding/loading' },
|
|
322
|
+
{ description: 'arbitrary path', returnUri: 'https://app.marcoapp.io/onboarding/loading/unexpected' },
|
|
327
323
|
];
|
|
328
324
|
const oauthConnectionRoutes = [
|
|
329
325
|
{
|
|
@@ -337,6 +333,18 @@ describe('appwriteFunctions', () => {
|
|
|
337
333
|
requestSchema: appwriteFunctions.api.routes.accountConnection.requestSchema,
|
|
338
334
|
},
|
|
339
335
|
];
|
|
336
|
+
for (const { description, includesAccountId, requestSchema } of oauthConnectionRoutes) {
|
|
337
|
+
it(`accepts ${description} OAuth connection completing at production loading`, () => {
|
|
338
|
+
const connection = {
|
|
339
|
+
email: 'test-user@example.com',
|
|
340
|
+
kind: 'OAUTH',
|
|
341
|
+
provider: 'GMAIL',
|
|
342
|
+
returnUri: 'https://app.marcoapp.io/onboarding/loading',
|
|
343
|
+
};
|
|
344
|
+
const request = includesAccountId ? { accountId: 'account_1', connection } : { connection };
|
|
345
|
+
expect(v.safeParse(requestSchema, request).success).toBe(true);
|
|
346
|
+
});
|
|
347
|
+
}
|
|
340
348
|
for (const { connection, description, expected } of invalidOAuthConnections) {
|
|
341
349
|
for (const { description: routeDescription, includesAccountId, requestSchema } of oauthConnectionRoutes) {
|
|
342
350
|
it(`rejects ${routeDescription} OAuth connection with ${description}`, () => {
|
|
@@ -345,4 +353,18 @@ describe('appwriteFunctions', () => {
|
|
|
345
353
|
});
|
|
346
354
|
}
|
|
347
355
|
}
|
|
356
|
+
for (const { description, returnUri } of forbiddenOAuthReturnUris) {
|
|
357
|
+
for (const { description: routeDescription, includesAccountId, requestSchema } of oauthConnectionRoutes) {
|
|
358
|
+
it(`rejects ${routeDescription} OAuth connection with ${description} return URI`, () => {
|
|
359
|
+
const connection = {
|
|
360
|
+
email: 'test-user@example.com',
|
|
361
|
+
kind: 'OAUTH',
|
|
362
|
+
provider: 'GMAIL',
|
|
363
|
+
returnUri,
|
|
364
|
+
};
|
|
365
|
+
const request = includesAccountId ? { accountId: 'account_1', connection } : { connection };
|
|
366
|
+
expect(v.safeParse(requestSchema, request).success).toBe(false);
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
348
370
|
});
|