mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-10 01:16:39 +02:00
Fix/oas response (#2068)
* bug fix * bug fix * remove doc file * store fixes * bug fix * rollback deleted file * fix test * add url to token * return all tokens not just active * add url fix * PR comment * PR comment * PR comment * add the flag to the experimental options * fix env var name
This commit is contained in:
parent
1426d5be33
commit
aa589b5ff5
@ -30,22 +30,32 @@ interface ITokenUserRow {
|
||||
user_id: number;
|
||||
created_at: Date;
|
||||
}
|
||||
|
||||
const tokenRowReducer = (acc, tokenRow) => {
|
||||
const { userId, name, ...token } = tokenRow;
|
||||
const { userId, userName, userUsername, roleId, roleName, ...token } =
|
||||
tokenRow;
|
||||
if (!acc[tokenRow.secret]) {
|
||||
acc[tokenRow.secret] = {
|
||||
secret: token.secret,
|
||||
name: token.name,
|
||||
url: token.url,
|
||||
expiresAt: token.expires_at,
|
||||
createdAt: token.created_at,
|
||||
createdBy: token.created_by,
|
||||
roleId: token.role_id,
|
||||
role: {
|
||||
id: roleId,
|
||||
name: roleName,
|
||||
},
|
||||
users: [],
|
||||
};
|
||||
}
|
||||
const currentToken = acc[tokenRow.secret];
|
||||
if (userId) {
|
||||
currentToken.users.push({ userId, name });
|
||||
currentToken.users.push({
|
||||
id: userId,
|
||||
name: userName,
|
||||
username: userUsername,
|
||||
});
|
||||
}
|
||||
return acc;
|
||||
};
|
||||
@ -58,6 +68,7 @@ const toRow = (newToken: IPublicSignupTokenCreate) => {
|
||||
expires_at: newToken.expiresAt,
|
||||
created_by: newToken.createdBy || null,
|
||||
role_id: newToken.roleId,
|
||||
url: newToken.url,
|
||||
};
|
||||
};
|
||||
|
||||
@ -97,15 +108,19 @@ export class PublicSignupTokenStore implements IPublicSignupTokenStore {
|
||||
'token_project_users.secret',
|
||||
)
|
||||
.leftJoin(`users`, 'token_project_users.user_id', 'users.id')
|
||||
.leftJoin(`roles`, 'tokens.role_id', 'roles.id')
|
||||
.select(
|
||||
'tokens.secret',
|
||||
'tokens.name',
|
||||
'tokens.expires_at',
|
||||
'tokens.created_at',
|
||||
'tokens.created_by',
|
||||
'tokens.role_id',
|
||||
'token_project_users.user_id',
|
||||
'users.name',
|
||||
'tokens.url',
|
||||
'token_project_users.user_id as userId',
|
||||
'users.name as userName',
|
||||
'users.username as userUsername',
|
||||
'roles.id as roleId',
|
||||
'roles.name as roleName',
|
||||
);
|
||||
}
|
||||
|
||||
@ -137,9 +152,9 @@ export class PublicSignupTokenStore implements IPublicSignupTokenStore {
|
||||
): Promise<PublicSignupTokenSchema> {
|
||||
const response = await this.db<ITokenRow>(TABLE).insert(
|
||||
toRow(newToken),
|
||||
['created_at'],
|
||||
['*'],
|
||||
);
|
||||
return toTokens([response])[0];
|
||||
return toTokens(response)[0];
|
||||
}
|
||||
|
||||
async isValid(secret: string): Promise<boolean> {
|
||||
@ -163,14 +178,15 @@ export class PublicSignupTokenStore implements IPublicSignupTokenStore {
|
||||
}
|
||||
|
||||
async get(key: string): Promise<PublicSignupTokenSchema> {
|
||||
const row = await this.makeTokenUsersQuery()
|
||||
.where('secret', key)
|
||||
.first();
|
||||
const rows = await this.makeTokenUsersQuery().where(
|
||||
'tokens.secret',
|
||||
key,
|
||||
);
|
||||
|
||||
if (!row)
|
||||
throw new NotFoundError('Could not find a token with that key');
|
||||
|
||||
return toTokens([row])[0];
|
||||
if (rows.length > 0) {
|
||||
return toTokens(rows)[0];
|
||||
}
|
||||
throw new NotFoundError('Could not find public signup token.');
|
||||
}
|
||||
|
||||
async delete(secret: string): Promise<void> {
|
||||
|
@ -5,6 +5,7 @@ test('publicSignupTokenSchema', () => {
|
||||
const data: PublicSignupTokenSchema = {
|
||||
name: 'Default',
|
||||
secret: 'some-secret',
|
||||
url: 'http://localhost:4242/invite-link/some-secret',
|
||||
expiresAt: new Date().toISOString(),
|
||||
users: [],
|
||||
role: { name: 'Viewer ', type: 'type', id: 1 },
|
||||
|
@ -6,11 +6,22 @@ export const publicSignupTokenSchema = {
|
||||
$id: '#/components/schemas/publicSignupTokenSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['secret', 'name', 'expiresAt', 'createdAt', 'createdBy', 'role'],
|
||||
required: [
|
||||
'secret',
|
||||
'url',
|
||||
'name',
|
||||
'expiresAt',
|
||||
'createdAt',
|
||||
'createdBy',
|
||||
'role',
|
||||
],
|
||||
properties: {
|
||||
secret: {
|
||||
type: 'string',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
|
@ -92,13 +92,14 @@ describe('Public Signup API', () => {
|
||||
});
|
||||
|
||||
test('should get All', async () => {
|
||||
expect.assertions(1);
|
||||
expect.assertions(2);
|
||||
const appName = '123!23';
|
||||
|
||||
stores.clientApplicationsStore.upsert({ appName });
|
||||
stores.publicSignupTokenStore.create({
|
||||
stores.publicSignupTokenStore.insert({
|
||||
name: 'some-name',
|
||||
expiresAt: expireAt(),
|
||||
createdBy: 'johnDoe',
|
||||
});
|
||||
|
||||
return request
|
||||
@ -107,6 +108,7 @@ describe('Public Signup API', () => {
|
||||
.expect((res) => {
|
||||
const { tokens } = res.body;
|
||||
expect(tokens[0].name).toBe('some-name');
|
||||
expect(tokens[0].createdBy).toBe('johnDoe');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -13,7 +13,10 @@ import {
|
||||
resourceCreatedResponseSchema,
|
||||
} from '../../openapi/util/create-response-schema';
|
||||
import { serializeDates } from '../../types/serialize-dates';
|
||||
import { emptyResponse } from '../../openapi/util/standard-responses';
|
||||
import {
|
||||
emptyResponse,
|
||||
getStandardResponses,
|
||||
} from '../../openapi/util/standard-responses';
|
||||
import { PublicSignupTokenService } from '../../services/public-signup-token-service';
|
||||
import UserService from '../../services/user-service';
|
||||
import {
|
||||
@ -28,6 +31,7 @@ import { PublicSignupTokenCreateSchema } from '../../openapi/spec/public-signup-
|
||||
import { PublicSignupTokenUpdateSchema } from '../../openapi/spec/public-signup-token-update-schema';
|
||||
import { CreateUserSchema } from '../../openapi/spec/create-user-schema';
|
||||
import { UserSchema, userSchema } from '../../openapi/spec/user-schema';
|
||||
import { extractUsername } from '../../util/extract-user';
|
||||
|
||||
interface TokenParam {
|
||||
token: string;
|
||||
@ -76,7 +80,7 @@ export class PublicSignupController extends Controller {
|
||||
tags: ['Public signup tokens'],
|
||||
operationId: 'getAllPublicSignupTokens',
|
||||
responses: {
|
||||
200: createResponseSchema('publicSignupTokenSchema'),
|
||||
200: createResponseSchema('publicSignupTokensSchema'),
|
||||
},
|
||||
}),
|
||||
],
|
||||
@ -115,6 +119,7 @@ export class PublicSignupController extends Controller {
|
||||
requestBody: createRequestSchema('createUserSchema'),
|
||||
responses: {
|
||||
200: createResponseSchema('userSchema'),
|
||||
...getStandardResponses(409),
|
||||
},
|
||||
}),
|
||||
],
|
||||
@ -195,7 +200,7 @@ export class PublicSignupController extends Controller {
|
||||
req: IAuthRequest,
|
||||
res: Response<PublicSignupTokensSchema>,
|
||||
): Promise<void> {
|
||||
const tokens = await this.publicSignupTokenService.getAllActiveTokens();
|
||||
const tokens = await this.publicSignupTokenService.getAllTokens();
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
@ -237,7 +242,6 @@ export class PublicSignupController extends Controller {
|
||||
token,
|
||||
req.body,
|
||||
);
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
201,
|
||||
res,
|
||||
@ -250,15 +254,16 @@ export class PublicSignupController extends Controller {
|
||||
req: IAuthRequest<void, void, PublicSignupTokenCreateSchema>,
|
||||
res: Response<PublicSignupTokenSchema>,
|
||||
): Promise<void> {
|
||||
const username = extractUsername(req);
|
||||
const token =
|
||||
await this.publicSignupTokenService.createNewPublicSignupToken(
|
||||
req.body,
|
||||
req.user.name,
|
||||
username,
|
||||
);
|
||||
this.openApiService.respondWithValidation(
|
||||
201,
|
||||
res,
|
||||
publicSignupTokensSchema.$id,
|
||||
publicSignupTokenSchema.$id,
|
||||
serializeDates(token),
|
||||
{ location: `tokens/${token.secret}` },
|
||||
);
|
||||
@ -288,8 +293,9 @@ export class PublicSignupController extends Controller {
|
||||
res: Response,
|
||||
): Promise<void> {
|
||||
const { token } = req.params;
|
||||
const username = extractUsername(req);
|
||||
|
||||
await this.publicSignupTokenService.delete(token, req.user.name);
|
||||
await this.publicSignupTokenService.delete(token, username);
|
||||
res.status(200).end();
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import {
|
||||
} from '../types/events';
|
||||
import UserService, { ICreateUser } from './user-service';
|
||||
import { IUser } from '../types/user';
|
||||
import { URL } from 'url';
|
||||
|
||||
export class PublicSignupTokenService {
|
||||
private store: IPublicSignupTokenStore;
|
||||
@ -29,6 +30,8 @@ export class PublicSignupTokenService {
|
||||
|
||||
private timer: NodeJS.Timeout;
|
||||
|
||||
private readonly unleashBase: string;
|
||||
|
||||
constructor(
|
||||
{
|
||||
publicSignupTokenStore,
|
||||
@ -38,7 +41,7 @@ export class PublicSignupTokenService {
|
||||
IUnleashStores,
|
||||
'publicSignupTokenStore' | 'roleStore' | 'eventStore'
|
||||
>,
|
||||
config: Pick<IUnleashConfig, 'getLogger' | 'authentication'>,
|
||||
config: Pick<IUnleashConfig, 'getLogger' | 'authentication' | 'server'>,
|
||||
userService: UserService,
|
||||
) {
|
||||
this.store = publicSignupTokenStore;
|
||||
@ -48,6 +51,13 @@ export class PublicSignupTokenService {
|
||||
this.logger = config.getLogger(
|
||||
'/services/public-signup-token-service.ts',
|
||||
);
|
||||
this.unleashBase = config.server.unleashUrl;
|
||||
}
|
||||
|
||||
private getUrl(secret: string): string {
|
||||
return new URL(
|
||||
`${this.unleashBase}/invite-link/${secret}/signup`,
|
||||
).toString();
|
||||
}
|
||||
|
||||
public async get(secret: string): Promise<PublicSignupTokenSchema> {
|
||||
@ -77,11 +87,13 @@ export class PublicSignupTokenService {
|
||||
secret: string,
|
||||
createUser: ICreateUser,
|
||||
): Promise<IUser> {
|
||||
const token = await this.get(secret);
|
||||
createUser.rootRole = token.role.id;
|
||||
const user = await this.userService.createUser(createUser);
|
||||
await this.store.addTokenUser(secret, user.id);
|
||||
await this.eventStore.store(
|
||||
new PublicSignupTokenUserAddedEvent({
|
||||
createdBy: 'userId',
|
||||
createdBy: 'System',
|
||||
data: { secret, userId: user.id },
|
||||
}),
|
||||
);
|
||||
@ -109,26 +121,29 @@ export class PublicSignupTokenService {
|
||||
createdBy: string,
|
||||
): Promise<PublicSignupTokenSchema> {
|
||||
const viewerRole = await this.roleStore.getRoleByName(RoleName.VIEWER);
|
||||
const secret = this.generateSecretKey();
|
||||
const url = this.getUrl(secret);
|
||||
const newToken: IPublicSignupTokenCreate = {
|
||||
name: tokenCreate.name,
|
||||
expiresAt: new Date(tokenCreate.expiresAt),
|
||||
secret: this.generateSecretKey(),
|
||||
secret: secret,
|
||||
roleId: viewerRole ? viewerRole.id : -1,
|
||||
createdBy: createdBy,
|
||||
url: url,
|
||||
};
|
||||
const token = await this.store.insert(newToken);
|
||||
|
||||
await this.eventStore.store(
|
||||
new PublicSignupTokenCreatedEvent({
|
||||
createdBy: createdBy,
|
||||
data: newToken,
|
||||
data: token,
|
||||
}),
|
||||
);
|
||||
return token;
|
||||
}
|
||||
|
||||
private generateSecretKey(): string {
|
||||
return crypto.randomBytes(32).toString('hex');
|
||||
return crypto.randomBytes(16).toString('hex');
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
|
@ -18,6 +18,10 @@ export const defaultExperimentalOptions = {
|
||||
process.env.UNLEASH_EXPERIMENTAL_BATCH_METRICS,
|
||||
false,
|
||||
),
|
||||
publicSignup: parseEnvVarBoolean(
|
||||
process.env.UNLEASH_EXPERIMENTAL_PUBLIC_SIGNUP,
|
||||
false,
|
||||
),
|
||||
},
|
||||
externalResolver: { isEnabled: (): boolean => false },
|
||||
};
|
||||
|
@ -6,6 +6,7 @@ export interface IPublicSignupTokenCreate {
|
||||
roleId: number;
|
||||
secret: string;
|
||||
createdBy: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface IPublicSignupToken extends IPublicSignupTokenCreate {
|
||||
|
@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
exports.up = function (db, callback) {
|
||||
db.runSql(
|
||||
`
|
||||
ALTER table public_signup_tokens
|
||||
ADD COLUMN IF NOT EXISTS url text
|
||||
`,
|
||||
callback,
|
||||
);
|
||||
};
|
||||
|
||||
exports.down = function (db, callback) {
|
||||
db.runSql(
|
||||
`
|
||||
ALTER table public_signup_tokens
|
||||
DROP COLUMN url
|
||||
`,
|
||||
callback,
|
||||
);
|
||||
};
|
223
src/test/e2e/api/admin/public-signup-token.e2e.test.ts
Normal file
223
src/test/e2e/api/admin/public-signup-token.e2e.test.ts
Normal file
@ -0,0 +1,223 @@
|
||||
import { setupAppWithCustomAuth } from '../../helpers/test-helper';
|
||||
import dbInit from '../../helpers/database-init';
|
||||
import getLogger from '../../../fixtures/no-logger';
|
||||
import { RoleName } from '../../../../lib/types/model';
|
||||
import { PublicSignupTokenCreateSchema } from '../../../../lib/openapi/spec/public-signup-token-create-schema';
|
||||
import { CreateUserSchema } from '../../../../lib/openapi/spec/create-user-schema';
|
||||
|
||||
let stores;
|
||||
let db;
|
||||
|
||||
jest.mock('../../../../lib/util/flag-resolver', () => {
|
||||
return jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
getAll: jest.fn(),
|
||||
isEnabled: jest.fn().mockResolvedValue(true),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
db = await dbInit('test', getLogger);
|
||||
stores = db.stores;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await stores.publicSignupTokenStore.deleteAll();
|
||||
await stores.eventStore.deleteAll();
|
||||
await stores.userStore.deleteAll();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
if (db) {
|
||||
await db.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
const expireAt = (addDays: number = 7): Date => {
|
||||
let now = new Date();
|
||||
now.setDate(now.getDate() + addDays);
|
||||
return now;
|
||||
};
|
||||
|
||||
test('admin users should be able to create a token', async () => {
|
||||
expect.assertions(3);
|
||||
|
||||
const preHook = (app, config, { userService, accessService }) => {
|
||||
app.use('/api/admin/', async (req, res, next) => {
|
||||
const role = await accessService.getRootRole(RoleName.ADMIN);
|
||||
const user = await userService.createUser({
|
||||
email: 'admin@example.com',
|
||||
rootRole: role.id,
|
||||
});
|
||||
req.user = user;
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
|
||||
|
||||
const tokenCreate: PublicSignupTokenCreateSchema = {
|
||||
name: 'some-name',
|
||||
expiresAt: expireAt().toISOString(),
|
||||
};
|
||||
|
||||
await request
|
||||
.post('/api/admin/invite-link/tokens')
|
||||
.send(tokenCreate)
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(201)
|
||||
.expect((res) => {
|
||||
expect(res.body.name).toBe('some-name');
|
||||
expect(res.body.secret).not.toBeNull();
|
||||
expect(res.body.url).not.toBeNull();
|
||||
});
|
||||
|
||||
await destroy();
|
||||
});
|
||||
|
||||
test('no permission to validate a token', async () => {
|
||||
const preHook = (app, config, { userService, accessService }) => {
|
||||
app.use('/api/admin/', async (req, res, next) => {
|
||||
const admin = await accessService.getRootRole(RoleName.ADMIN);
|
||||
await userService.createUser({
|
||||
email: 'admin@example.com',
|
||||
username: 'admin@example.com',
|
||||
rootRole: admin.id,
|
||||
});
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
|
||||
|
||||
await stores.publicSignupTokenStore.insert({
|
||||
name: 'some-name',
|
||||
expiresAt: expireAt(),
|
||||
secret: 'some-secret',
|
||||
createAt: new Date(),
|
||||
createdBy: 'admin@example.com',
|
||||
roleId: 3,
|
||||
});
|
||||
await request
|
||||
.post('/api/admin/invite-link/tokens/some-secret/validate')
|
||||
.expect(200);
|
||||
|
||||
await destroy();
|
||||
});
|
||||
|
||||
test('should return 401 if token can not be validate', async () => {
|
||||
const preHook = (app, config, { userService, accessService }) => {
|
||||
app.use('/api/admin/', async (req, res, next) => {
|
||||
const admin = await accessService.getRootRole(RoleName.ADMIN);
|
||||
await userService.createUser({
|
||||
email: 'admin@example.com',
|
||||
username: 'admin@example.com',
|
||||
rootRole: admin.id,
|
||||
});
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
|
||||
|
||||
await request
|
||||
.post('/api/admin/invite-link/tokens/some-invalid-secret/validate')
|
||||
.expect(401);
|
||||
|
||||
await destroy();
|
||||
});
|
||||
|
||||
test('users can signup with invite-link', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const preHook = (app, config, { userService, accessService }) => {
|
||||
app.use('/api/admin/', async (req, res, next) => {
|
||||
const admin = await accessService.getRootRole(RoleName.ADMIN);
|
||||
await userService.createUser({
|
||||
email: 'admin@example.com',
|
||||
username: 'admin@example.com',
|
||||
rootRole: admin.id,
|
||||
});
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
|
||||
|
||||
await stores.publicSignupTokenStore.insert({
|
||||
name: 'some-name',
|
||||
expiresAt: expireAt(),
|
||||
secret: 'some-secret',
|
||||
url: 'http://localhost:4242/invite-lint/some-secret/signup',
|
||||
createAt: new Date(),
|
||||
createdBy: 'admin@example.com',
|
||||
roleId: 3,
|
||||
});
|
||||
|
||||
const createUser: CreateUserSchema = {
|
||||
username: 'some-username',
|
||||
email: 'some@example.com',
|
||||
password: 'eweggwEG',
|
||||
sendEmail: false,
|
||||
rootRole: 1,
|
||||
};
|
||||
|
||||
await request
|
||||
.post('/api/admin/invite-link/tokens/some-secret/signup')
|
||||
.send(createUser)
|
||||
.expect(201)
|
||||
.expect((res) => {
|
||||
const user = res.body;
|
||||
expect(user.username).toBe('some-username');
|
||||
});
|
||||
|
||||
await destroy();
|
||||
});
|
||||
|
||||
test('can get a token with users', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const preHook = (app, config, { userService, accessService }) => {
|
||||
app.use('/api/admin/', async (req, res, next) => {
|
||||
const role = await accessService.getRootRole(RoleName.ADMIN);
|
||||
const user = await userService.createUser({
|
||||
email: 'admin@example.com',
|
||||
rootRole: role.id,
|
||||
});
|
||||
req.user = user;
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
|
||||
|
||||
await stores.publicSignupTokenStore.insert({
|
||||
name: 'some-name',
|
||||
expiresAt: expireAt(),
|
||||
secret: 'some-secret',
|
||||
createAt: new Date(),
|
||||
createdBy: 'admin@example.com',
|
||||
roleId: 3,
|
||||
});
|
||||
|
||||
const user = await stores.userStore.insert({
|
||||
username: 'some-username',
|
||||
email: 'some@example.com',
|
||||
password: 'eweggwEG',
|
||||
sendEmail: false,
|
||||
rootRole: 3,
|
||||
});
|
||||
|
||||
await stores.publicSignupTokenStore.addTokenUser('some-secret', user.id);
|
||||
|
||||
await request
|
||||
.get('/api/admin/invite-link/tokens/some-secret')
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
const token = res.body;
|
||||
expect(token.users.length).toEqual(1);
|
||||
});
|
||||
|
||||
await destroy();
|
||||
});
|
@ -2432,6 +2432,9 @@ exports[`should serve the OpenAPI spec 1`] = `
|
||||
"secret": {
|
||||
"type": "string",
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
},
|
||||
"users": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/userSchema",
|
||||
@ -2442,6 +2445,7 @@ exports[`should serve the OpenAPI spec 1`] = `
|
||||
},
|
||||
"required": [
|
||||
"secret",
|
||||
"url",
|
||||
"name",
|
||||
"expiresAt",
|
||||
"createdAt",
|
||||
@ -4512,11 +4516,11 @@ If the provided project does not exist, the list of events will be empty.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/publicSignupTokenSchema",
|
||||
"$ref": "#/components/schemas/publicSignupTokensSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "publicSignupTokenSchema",
|
||||
"description": "publicSignupTokensSchema",
|
||||
},
|
||||
},
|
||||
"tags": [
|
||||
@ -4680,6 +4684,9 @@ If the provided project does not exist, the list of events will be empty.",
|
||||
},
|
||||
"description": "userSchema",
|
||||
},
|
||||
"409": {
|
||||
"description": "The provided resource can not be created or updated because it would conflict with the current state of the resource or with an already existing resource, respectively.",
|
||||
},
|
||||
},
|
||||
"tags": [
|
||||
"Public signup tokens",
|
||||
|
@ -47,13 +47,14 @@ export default class FakePublicSignupStore implements IPublicSignupTokenStore {
|
||||
expiresAt: newToken.expiresAt.toISOString(),
|
||||
createdAt: new Date().toISOString(),
|
||||
users: [],
|
||||
url: 'some=url',
|
||||
name: newToken.name,
|
||||
role: {
|
||||
name: 'Viewer',
|
||||
type: '',
|
||||
id: 1,
|
||||
},
|
||||
createdBy: null,
|
||||
createdBy: newToken.createdBy,
|
||||
};
|
||||
this.tokens.push(token);
|
||||
return Promise.resolve(token);
|
||||
@ -80,6 +81,6 @@ export default class FakePublicSignupStore implements IPublicSignupTokenStore {
|
||||
|
||||
// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
|
||||
async getAll(query?: Object): Promise<PublicSignupTokenSchema[]> {
|
||||
return Promise.resolve([]);
|
||||
return Promise.resolve(this.tokens);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user