Skip to content

Commit b201cc3

Browse files
committed
tests: add VAG tests
1 parent fdbd6a0 commit b201cc3

1 file changed

Lines changed: 320 additions & 0 deletions

File tree

infrastructure/evault-core/src/core/protocol/vault-access-guard.spec.ts

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,5 +427,325 @@ describe("VaultAccessGuard", () => {
427427
expect(result).toBeNull();
428428
});
429429
});
430+
431+
describe("Authentication Validation (Security Tests)", () => {
432+
it("should reject getAllEnvelopes without authentication (no token, no eName)", async () => {
433+
const context = createMockContext({
434+
// No eName, no token
435+
eName: null,
436+
request: {
437+
headers: new Headers({}),
438+
} as any,
439+
});
440+
441+
const mockResolver = vi.fn(async () => {
442+
return [{ id: "envelope-1", ontology: "Test", value: { data: "secret" } }];
443+
});
444+
445+
const wrappedResolver = guard.middleware(mockResolver);
446+
447+
await expect(
448+
wrappedResolver(null, {}, context)
449+
).rejects.toThrow("Authentication required");
450+
451+
// CRITICAL: Resolver should NOT be executed
452+
expect(mockResolver).not.toHaveBeenCalled();
453+
});
454+
455+
it("should reject getAllEnvelopes with empty eName", async () => {
456+
const context = createMockContext({
457+
eName: "",
458+
request: {
459+
headers: new Headers({}),
460+
} as any,
461+
});
462+
463+
const mockResolver = vi.fn(async () => {
464+
return [{ id: "envelope-1", ontology: "Test", value: { data: "secret" } }];
465+
});
466+
467+
const wrappedResolver = guard.middleware(mockResolver);
468+
469+
// Empty string is falsy, so it will throw the first authentication error
470+
await expect(
471+
wrappedResolver(null, {}, context)
472+
).rejects.toThrow("Authentication required");
473+
474+
// CRITICAL: Resolver should NOT be executed
475+
expect(mockResolver).not.toHaveBeenCalled();
476+
});
477+
478+
it("should reject getAllEnvelopes with whitespace-only eName", async () => {
479+
const context = createMockContext({
480+
eName: " ",
481+
request: {
482+
headers: new Headers({}),
483+
} as any,
484+
});
485+
486+
const mockResolver = vi.fn(async () => {
487+
return [{ id: "envelope-1", ontology: "Test", value: { data: "secret" } }];
488+
});
489+
490+
const wrappedResolver = guard.middleware(mockResolver);
491+
492+
// Whitespace-only string will be caught by the trim check
493+
await expect(
494+
wrappedResolver(null, {}, context)
495+
).rejects.toThrow("Invalid X-ENAME header");
496+
497+
// CRITICAL: Resolver should NOT be executed
498+
expect(mockResolver).not.toHaveBeenCalled();
499+
});
500+
501+
it("should allow getAllEnvelopes with valid eName", async () => {
502+
const eName = "test@example.com";
503+
const context = createMockContext({
504+
eName,
505+
request: {
506+
headers: new Headers({}),
507+
} as any,
508+
});
509+
510+
const mockResolver = vi.fn(async () => {
511+
return [{ id: "envelope-1", ontology: "Test", value: { data: "test" } }];
512+
});
513+
514+
const wrappedResolver = guard.middleware(mockResolver);
515+
const result = await wrappedResolver(null, {}, context);
516+
517+
// Should execute and return results
518+
expect(result).toBeDefined();
519+
expect(mockResolver).toHaveBeenCalled();
520+
});
521+
522+
it("should allow getAllEnvelopes with valid Bearer token", async () => {
523+
const token = await createValidToken({ platform: "test-platform" });
524+
const context = createMockContext({
525+
eName: null,
526+
request: {
527+
headers: new Headers({
528+
authorization: `Bearer ${token}`,
529+
}),
530+
} as any,
531+
});
532+
533+
const mockResolver = vi.fn(async () => {
534+
return [{ id: "envelope-1", ontology: "Test", value: { data: "test" } }];
535+
});
536+
537+
const wrappedResolver = guard.middleware(mockResolver);
538+
const result = await wrappedResolver(null, {}, context);
539+
540+
// Should execute and return results
541+
expect(result).toBeDefined();
542+
expect(mockResolver).toHaveBeenCalled();
543+
expect(context.tokenPayload).toBeDefined();
544+
});
545+
546+
it("should reject findMetaEnvelopesByOntology without authentication", async () => {
547+
const context = createMockContext({
548+
eName: null,
549+
request: {
550+
headers: new Headers({}),
551+
} as any,
552+
});
553+
554+
const mockResolver = vi.fn(async () => {
555+
return [{ id: "envelope-1", ontology: "Test", acl: ["*"] }];
556+
});
557+
558+
const wrappedResolver = guard.middleware(mockResolver);
559+
560+
await expect(
561+
wrappedResolver(null, { ontology: "Test" }, context)
562+
).rejects.toThrow("Authentication required");
563+
564+
// CRITICAL: Resolver should NOT be executed
565+
expect(mockResolver).not.toHaveBeenCalled();
566+
});
567+
568+
it("should reject searchMetaEnvelopes without authentication", async () => {
569+
const context = createMockContext({
570+
eName: null,
571+
request: {
572+
headers: new Headers({}),
573+
} as any,
574+
});
575+
576+
const mockResolver = vi.fn(async () => {
577+
return [{ id: "envelope-1", ontology: "Test", acl: ["*"] }];
578+
});
579+
580+
const wrappedResolver = guard.middleware(mockResolver);
581+
582+
await expect(
583+
wrappedResolver(null, { ontology: "Test", term: "search" }, context)
584+
).rejects.toThrow("Authentication required");
585+
586+
// CRITICAL: Resolver should NOT be executed
587+
expect(mockResolver).not.toHaveBeenCalled();
588+
});
589+
590+
it("should reject storeMetaEnvelope mutation without authentication", async () => {
591+
const context = createMockContext({
592+
eName: null,
593+
request: {
594+
headers: new Headers({}),
595+
} as any,
596+
});
597+
598+
const mockResolver = vi.fn(async () => {
599+
return {
600+
metaEnvelope: { id: "new-envelope", ontology: "Test" },
601+
envelopes: [],
602+
};
603+
});
604+
605+
const wrappedResolver = guard.middleware(mockResolver);
606+
607+
await expect(
608+
wrappedResolver(null, { input: { ontology: "Test", payload: {}, acl: [] } }, context)
609+
).rejects.toThrow("Authentication required");
610+
611+
// CRITICAL: Resolver should NOT be executed
612+
expect(mockResolver).not.toHaveBeenCalled();
613+
});
614+
615+
it("should reject deleteMetaEnvelope mutation without authentication", async () => {
616+
const context = createMockContext({
617+
eName: null,
618+
request: {
619+
headers: new Headers({}),
620+
} as any,
621+
});
622+
623+
const mockResolver = vi.fn(async () => {
624+
return true;
625+
});
626+
627+
const wrappedResolver = guard.middleware(mockResolver);
628+
629+
await expect(
630+
wrappedResolver(null, { id: "envelope-id" }, context)
631+
).rejects.toThrow("Authentication required");
632+
633+
// CRITICAL: Resolver should NOT be executed
634+
expect(mockResolver).not.toHaveBeenCalled();
635+
});
636+
637+
it("should reject updateEnvelopeValue mutation without authentication", async () => {
638+
const context = createMockContext({
639+
eName: null,
640+
request: {
641+
headers: new Headers({}),
642+
} as any,
643+
});
644+
645+
const mockResolver = vi.fn(async () => {
646+
return true;
647+
});
648+
649+
const wrappedResolver = guard.middleware(mockResolver);
650+
651+
await expect(
652+
wrappedResolver(null, { envelopeId: "envelope-id", newValue: {} }, context)
653+
).rejects.toThrow("Authentication required");
654+
655+
// CRITICAL: Resolver should NOT be executed
656+
expect(mockResolver).not.toHaveBeenCalled();
657+
});
658+
659+
it("should reject getMetaEnvelopeById without authentication", async () => {
660+
const context = createMockContext({
661+
eName: null,
662+
request: {
663+
headers: new Headers({}),
664+
} as any,
665+
});
666+
667+
const mockResolver = vi.fn(async () => {
668+
return { id: "envelope-1", ontology: "Test", acl: ["*"] };
669+
});
670+
671+
const wrappedResolver = guard.middleware(mockResolver);
672+
673+
await expect(
674+
wrappedResolver(null, { id: "envelope-id" }, context)
675+
).rejects.toThrow("Authentication required");
676+
677+
// CRITICAL: Resolver should NOT be executed
678+
expect(mockResolver).not.toHaveBeenCalled();
679+
});
680+
681+
it("should allow operations with valid eName even without token", async () => {
682+
const eName = "test@example.com";
683+
const context = createMockContext({
684+
eName,
685+
request: {
686+
headers: new Headers({}),
687+
} as any,
688+
});
689+
690+
const mockResolver = vi.fn(async () => {
691+
return [{ id: "envelope-1", ontology: "Test", value: {} }];
692+
});
693+
694+
const wrappedResolver = guard.middleware(mockResolver);
695+
const result = await wrappedResolver(null, {}, context);
696+
697+
// Should execute successfully
698+
expect(result).toBeDefined();
699+
expect(mockResolver).toHaveBeenCalled();
700+
});
701+
702+
it("should allow operations with valid token even without eName", async () => {
703+
const token = await createValidToken({ platform: "test-platform" });
704+
const context = createMockContext({
705+
eName: null,
706+
request: {
707+
headers: new Headers({
708+
authorization: `Bearer ${token}`,
709+
}),
710+
} as any,
711+
});
712+
713+
const mockResolver = vi.fn(async () => {
714+
return [{ id: "envelope-1", ontology: "Test", value: {} }];
715+
});
716+
717+
const wrappedResolver = guard.middleware(mockResolver);
718+
const result = await wrappedResolver(null, {}, context);
719+
720+
// Should execute successfully
721+
expect(result).toBeDefined();
722+
expect(mockResolver).toHaveBeenCalled();
723+
expect(context.tokenPayload).toBeDefined();
724+
});
725+
726+
it("should reject with invalid Bearer token format", async () => {
727+
const context = createMockContext({
728+
eName: null,
729+
request: {
730+
headers: new Headers({
731+
authorization: "InvalidFormat token",
732+
}),
733+
} as any,
734+
});
735+
736+
const mockResolver = vi.fn(async () => {
737+
return [{ id: "envelope-1", ontology: "Test", value: {} }];
738+
});
739+
740+
const wrappedResolver = guard.middleware(mockResolver);
741+
742+
await expect(
743+
wrappedResolver(null, {}, context)
744+
).rejects.toThrow("Authentication required");
745+
746+
// CRITICAL: Resolver should NOT be executed
747+
expect(mockResolver).not.toHaveBeenCalled();
748+
});
749+
});
430750
});
431751

0 commit comments

Comments
 (0)