Skip to content

Commit 32dbe99

Browse files
committed
Added: GetCurrentApiToken use case
1 parent 7db3f1a commit 32dbe99

File tree

11 files changed

+128
-3
lines changed

11 files changed

+128
-3
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface ApiTokenInfo {
2+
apiToken: string
3+
expirationDate: Date
4+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { ApiTokenInfo } from '../models/ApiTokenInfo'
12
import { AuthenticatedUser } from '../models/AuthenticatedUser'
23

34
export interface IUsersRepository {
45
getCurrentAuthenticatedUser(): Promise<AuthenticatedUser>
56
recreateApiToken(): Promise<string>
7+
getCurrentApiToken(): Promise<ApiTokenInfo>
68
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { ApiTokenInfo } from '../models/ApiTokenInfo'
3+
import { IUsersRepository } from '../repositories/IUsersRepository'
4+
5+
export class GetCurrentApiToken implements UseCase<ApiTokenInfo> {
6+
private usersRepository: IUsersRepository
7+
8+
constructor(usersRepository: IUsersRepository) {
9+
this.usersRepository = usersRepository
10+
}
11+
12+
/**
13+
* Returns the current API token information corresponding to the current user authenticated through ApiConfig.
14+
*
15+
* @returns {Promise<ApiTokenInfo>}
16+
*/
17+
async execute(): Promise<ApiTokenInfo> {
18+
return await this.usersRepository.getCurrentApiToken()
19+
}
20+
}

src/users/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { UsersRepository } from './infra/repositories/UsersRepository'
22
import { GetCurrentAuthenticatedUser } from './domain/useCases/GetCurrentAuthenticatedUser'
33
import { RecreateApiToken } from './domain/useCases/RecreateApiToken'
4+
import { GetCurrentApiToken } from './domain/useCases/GetCurrentApiToken'
45

56
const usersRepository = new UsersRepository()
67

78
const getCurrentAuthenticatedUser = new GetCurrentAuthenticatedUser(usersRepository)
89
const recreateApiToken = new RecreateApiToken(usersRepository)
10+
const getCurrentApiToken = new GetCurrentApiToken(usersRepository)
911

10-
export { getCurrentAuthenticatedUser, recreateApiToken }
12+
export { getCurrentAuthenticatedUser, recreateApiToken, getCurrentApiToken }
1113
export { AuthenticatedUser } from './domain/models/AuthenticatedUser'

src/users/infra/repositories/UsersRepository.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { ApiRepository } from '../../../core/infra/repositories/ApiRepository'
22
import { IUsersRepository } from '../../domain/repositories/IUsersRepository'
33
import { AuthenticatedUser } from '../../domain/models/AuthenticatedUser'
44
import { AxiosResponse } from 'axios'
5+
import { ApiTokenInfo } from '../../domain/models/ApiTokenInfo'
6+
import { transformApiTokenInfoResponseToApiTokenInfo } from './transformers/apiTokenInfoTransformers'
57

68
export class UsersRepository extends ApiRepository implements IUsersRepository {
79
private readonly usersResourceName: string = 'users'
@@ -22,6 +24,14 @@ export class UsersRepository extends ApiRepository implements IUsersRepository {
2224
})
2325
}
2426

27+
public async getCurrentApiToken(): Promise<ApiTokenInfo> {
28+
return this.doGet(`/${this.usersResourceName}/token`, true)
29+
.then((response) => transformApiTokenInfoResponseToApiTokenInfo(response))
30+
.catch((error) => {
31+
throw error
32+
})
33+
}
34+
2535
private getAuthenticatedUserFromResponse(response: AxiosResponse): AuthenticatedUser {
2636
const responseData = response.data.data
2737
return {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { AxiosResponse } from 'axios'
2+
import { ApiTokenInfo } from '../../../domain/models/ApiTokenInfo'
3+
4+
export const transformApiTokenInfoResponseToApiTokenInfo = (
5+
response: AxiosResponse
6+
): ApiTokenInfo => {
7+
const apiTokenInfoPayload = response.data.data
8+
const messageParts = apiTokenInfoPayload.message.split(' ')
9+
const expirationDateFormattedTimestamp = `${messageParts[4]}T${messageParts[5]}`
10+
return {
11+
apiToken: messageParts[1],
12+
expirationDate: new Date(expirationDateFormattedTimestamp)
13+
}
14+
}

test/environment/.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
POSTGRES_VERSION=13
22
DATAVERSE_DB_USER=dataverse
33
SOLR_VERSION=9.3.0
4-
DATAVERSE_IMAGE_REGISTRY=docker.io
5-
DATAVERSE_IMAGE_TAG=unstable
4+
DATAVERSE_IMAGE_REGISTRY=ghcr.io
5+
DATAVERSE_IMAGE_TAG=10857-add-expiration-date-to-recreate-token-api
66
DATAVERSE_BOOTSTRAP_TIMEOUT=5m
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { ApiConfig, getCurrentApiToken } from '../../../src'
2+
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
3+
import { TestConstants } from '../../testHelpers/TestConstants'
4+
5+
describe('execute', () => {
6+
beforeAll(async () => {
7+
ApiConfig.init(
8+
TestConstants.TEST_API_URL,
9+
DataverseApiAuthMechanism.API_KEY,
10+
process.env.TEST_API_KEY
11+
)
12+
})
13+
14+
test('should return the current API token', async () => {
15+
const actualTokenInfo = await getCurrentApiToken.execute()
16+
expect(actualTokenInfo.apiToken).toBe(process.env.TEST_API_KEY)
17+
expect(typeof actualTokenInfo.expirationDate).toBe('object')
18+
})
19+
})

test/functional/users/RecreateApiToken.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import { TestConstants } from '../../testHelpers/TestConstants'
44
import { createApiTokenViaApi } from '../../testHelpers/users/apiTokenHelper'
55

66
describe('execute', () => {
7+
beforeAll(async () => {
8+
ApiConfig.init(
9+
TestConstants.TEST_API_URL,
10+
DataverseApiAuthMechanism.API_KEY,
11+
process.env.TEST_API_KEY
12+
)
13+
})
14+
715
afterAll(async () => {
816
ApiConfig.init(
917
TestConstants.TEST_API_URL,

test/integration/users/UsersRepository.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,24 @@ describe('UsersRepository', () => {
5252
await expect(sut.recreateApiToken()).rejects.toThrow(errorExpected)
5353
})
5454
})
55+
56+
describe('getCurrentApiToken', () => {
57+
test('should return API token info when valid authentication is provided', async () => {
58+
ApiConfig.init(
59+
TestConstants.TEST_API_URL,
60+
DataverseApiAuthMechanism.API_KEY,
61+
process.env.TEST_API_KEY
62+
)
63+
const actualApiTokenInfo = await sut.getCurrentApiToken()
64+
expect(actualApiTokenInfo.apiToken).toBe(process.env.TEST_API_KEY)
65+
expect(typeof actualApiTokenInfo.expirationDate).toBe('object')
66+
})
67+
68+
test('should return error when authentication is not valid', async () => {
69+
ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.API_KEY, 'invalidApiKey')
70+
71+
const errorExpected: ReadError = new ReadError('[401] Bad API key')
72+
await expect(sut.getCurrentApiToken()).rejects.toThrow(errorExpected)
73+
})
74+
})
5575
})

0 commit comments

Comments
 (0)