mirror of
https://github.com/graphql-hive/console
synced 2026-05-22 16:48:56 +00:00
* add supertoken container to docker-compose file * yeah I am sorry this one big commit and I am ashamed of it * use logOut function * feat: show header on 404 page * feat: better handling for organization cookie when not authenticated * wrap it * check session within server side props * add is_admin flag user migration * simplify and annotate the config * fix: handle status codes + fix email/password sign up with import from auth0 * no hardcoded env pls * decode process.env * secure update user id mapping via a key * fix: login form * lol we don't need to hit the API * fix: do graphql api authorization via authorization header instead of cookie * implement isAdmin flag * fix: types :) * skipit * yo we can run this * set env variables * disable because it annoys the hell out of me * use the right host * add not about token length * refactor: decode environment variables * feat: store external user id from guthub/google provider in the database * workaround supertokens omitting null values from the token * re-enable check * i have no time for this shit * add missing env variable * fix: email test; missing domain extension * configure pulumi deployment Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> Co-authored-by: Dotan Simha <dotansimha@gmail.com> * configure pulumi deployment Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> Co-authored-by: Dotan Simha <dotansimha@gmail.com> * configure pulumi deployment Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> Co-authored-by: Dotan Simha <dotansimha@gmail.com> * configure pulumi deployment Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> * fix: env names * fix: link google account to the correct db record * feat: email confirmation emails * ? * bump ts-node * fix types * omit package form the bundle * remove it from dependencies... * add emails apckage to dev deps * resolve eslint issues * remove comments * update dev info + change env variable (no need to expose it on the frontend) * use correct user id lol Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> Co-authored-by: Dotan Simha <dotansimha@gmail.com>
120 lines
3.1 KiB
TypeScript
120 lines
3.1 KiB
TypeScript
import { TargetAccessScope, ProjectType, ProjectAccessScope, OrganizationAccessScope } from '@app/gql/graphql';
|
|
import { createOrganization, createProject, createToken, updateOrgRateLimit, waitFor } from '../../../testkit/flow';
|
|
import * as emails from '../../../testkit/emails';
|
|
import { authenticate, userEmails } from '../../../testkit/auth';
|
|
import { collect } from '../../../testkit/usage';
|
|
|
|
function generateUnique() {
|
|
return Math.random().toString(36).substring(7);
|
|
}
|
|
|
|
function filterEmailsByOrg(orgName: string, emails: emails.Email[]) {
|
|
return emails.filter(email => email.subject.startsWith(orgName));
|
|
}
|
|
|
|
test('rate limit approaching and reached for organization', async () => {
|
|
const adminEmail = userEmails.admin;
|
|
const { access_token } = await authenticate('admin');
|
|
const orgResult = await createOrganization(
|
|
{
|
|
name: generateUnique(),
|
|
},
|
|
access_token
|
|
);
|
|
|
|
const org = orgResult.body.data!.createOrganization.ok!.createdOrganizationPayload.organization;
|
|
const projectResult = await createProject(
|
|
{
|
|
organization: org.cleanId,
|
|
type: ProjectType.Single,
|
|
name: 'bar',
|
|
},
|
|
access_token
|
|
);
|
|
|
|
const project = projectResult.body.data!.createProject.ok!.createdProject;
|
|
const target = projectResult.body.data!.createProject.ok!.createdTargets.find(t => t.name === 'production')!;
|
|
|
|
await updateOrgRateLimit(
|
|
{
|
|
organization: org.cleanId,
|
|
},
|
|
{
|
|
operations: 11,
|
|
},
|
|
access_token
|
|
);
|
|
|
|
const tokenResult = await createToken(
|
|
{
|
|
name: 'test',
|
|
organization: org.cleanId,
|
|
project: project.cleanId,
|
|
target: target.cleanId,
|
|
organizationScopes: [OrganizationAccessScope.Read],
|
|
projectScopes: [ProjectAccessScope.Read],
|
|
targetScopes: [TargetAccessScope.Read, TargetAccessScope.RegistryRead, TargetAccessScope.RegistryWrite],
|
|
},
|
|
access_token
|
|
);
|
|
|
|
expect(tokenResult.body.errors).not.toBeDefined();
|
|
|
|
const token = tokenResult.body.data!.createToken.ok!.secret;
|
|
|
|
const op = {
|
|
operation: 'query ping { ping }',
|
|
operationName: 'ping',
|
|
fields: ['Query', 'Query.ping'],
|
|
execution: {
|
|
ok: true,
|
|
duration: 200000000,
|
|
errorsTotal: 0,
|
|
},
|
|
};
|
|
|
|
const collectResult = await collect({
|
|
operations: new Array(10).fill(op),
|
|
token,
|
|
});
|
|
|
|
expect(collectResult.status).toEqual(200);
|
|
|
|
await waitFor(5_000);
|
|
|
|
let sent = await emails.history();
|
|
expect(sent).toContainEqual({
|
|
to: adminEmail,
|
|
subject: `${org.name} is approaching its rate limit`,
|
|
body: expect.any(String),
|
|
});
|
|
expect(filterEmailsByOrg(org.name, sent)).toHaveLength(1);
|
|
|
|
await collect({
|
|
operations: [op, op],
|
|
token,
|
|
});
|
|
|
|
await waitFor(5_000);
|
|
|
|
sent = await emails.history();
|
|
|
|
expect(sent).toContainEqual({
|
|
to: adminEmail,
|
|
subject: `${org.name} has exceeded its rate limit`,
|
|
body: expect.any(String),
|
|
});
|
|
expect(filterEmailsByOrg(org.name, sent)).toHaveLength(2);
|
|
|
|
// Make sure we don't send the same email again
|
|
await collect({
|
|
operations: [op, op],
|
|
token,
|
|
});
|
|
|
|
await waitFor(5_000);
|
|
|
|
// Nothing new
|
|
sent = await emails.history();
|
|
expect(filterEmailsByOrg(org.name, sent)).toHaveLength(2);
|
|
});
|