From 3d7fbbdb95d37a40c517c65436ec8e2f9f65a3ee Mon Sep 17 00:00:00 2001 From: Thai Date: Wed, 26 Aug 2020 16:50:17 -0700 Subject: [PATCH 1/3] Made changes so auth on openapi schema works. Now requests that require BE to check token will be sent with Bearer JWT from FE as a token. --- package.json | 2 +- src/pages/App/index.js | 5 +- src/pages/EventSignInPage/index.js | 5 + src/services/ApiConfigStore.ts | 2 +- src/services/ApiEvents.ts | 80 +++++++++- src/services/api/.openapi-generator/FILES | 36 +++-- src/services/api/apis/EventApi.ts | 45 ++++++ src/services/api/apis/UserApi.ts | 137 ++++++++++++++++++ src/services/api/apis/index.ts | 1 + .../api/models/AppUserInductionClass.ts | 84 +++++++++++ .../api/models/AppUserProfileResponse.ts | 107 ++++++++++++++ .../api/models/AppUserRolesResponse.ts | 70 +++++++++ src/services/api/models/index.ts | 3 + 13 files changed, 556 insertions(+), 21 deletions(-) create mode 100644 src/services/api/apis/UserApi.ts create mode 100644 src/services/api/models/AppUserInductionClass.ts create mode 100644 src/services/api/models/AppUserProfileResponse.ts create mode 100644 src/services/api/models/AppUserRolesResponse.ts diff --git a/package.json b/package.json index 99474d8f..d336a394 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "storybook": "start-storybook -p 6006 -s public", "build-storybook": "build-storybook -s public", "precodegen": "rimraf src/api/*", - "codegen": "npx openapi-generator generate -i http://dev.api.hknucsd.com/api/docs/json -g typescript-fetch --additional-properties=typescriptThreePlus=true -o src/api/" + "codegen": "npx openapi-generator generate -i http://dev.api.hknucsd.com/api/docs/json -g typescript-fetch --additional-properties=typescriptThreePlus=true -o src/services/api" }, "eslintConfig": { "extends": "react-app" diff --git a/src/pages/App/index.js b/src/pages/App/index.js index 348d2862..eb015c50 100644 --- a/src/pages/App/index.js +++ b/src/pages/App/index.js @@ -25,6 +25,7 @@ import { InducteeRoutingPermission, OfficerRoutingPermission, } from '@HOCs/RoutingPermissions'; +import ApiConfigStore from '@Services/ApiConfigStore'; const INITIAL_STATES = { userClaims: null, @@ -42,7 +43,9 @@ class App extends React.Component { firebase.auth().onAuthStateChanged(async user => { if (user) { const tokenResult = await user.getIdTokenResult(); - const { claims } = tokenResult; + const { claims, token } = tokenResult; + + ApiConfigStore.setToken(token); this.setState({ userClaims: { diff --git a/src/pages/EventSignInPage/index.js b/src/pages/EventSignInPage/index.js index 44cbaec3..3c4d6b59 100644 --- a/src/pages/EventSignInPage/index.js +++ b/src/pages/EventSignInPage/index.js @@ -9,6 +9,7 @@ import styles from './styles'; import HKN_TRIDENT_LOGO from '@Images/hkn-trident.png'; import { Loading } from '@SharedComponents'; import { getEventById } from '@Services/events'; +import { signInToEvent } from '@Services/ApiEvents'; class EventSignInPage extends React.Component { constructor(props) { @@ -39,8 +40,12 @@ class EventSignInPage extends React.Component { } handleSubmit = (values, setSubmitting) => { + const { eventId } = this.state; + console.log(values); + signInToEvent(eventId, values); + setSubmitting(false); }; diff --git a/src/services/ApiConfigStore.ts b/src/services/ApiConfigStore.ts index 65a82af4..3863b601 100644 --- a/src/services/ApiConfigStore.ts +++ b/src/services/ApiConfigStore.ts @@ -19,7 +19,7 @@ class ApiConfigStoreClass { // this is gonna be called on login setToken(token: string) { - this.configParams.apiKey = token; + this.configParams.accessToken = token; this.config = new Configuration(this.configParams); } } diff --git a/src/services/ApiEvents.ts b/src/services/ApiEvents.ts index eff75291..acbd0ff8 100644 --- a/src/services/ApiEvents.ts +++ b/src/services/ApiEvents.ts @@ -1,5 +1,20 @@ -import { EventApi, EventControllerGetEventRequest } from './api/apis/EventApi'; -import { MultipleEventResponse, EventResponse } from './api/models'; +import { + EventApi, + EventControllerGetEventRequest, + EventControllerCreateEventRequest, + EventControllerDeleteEventRequest, + EventControllerUpdateEventRequest, + EventControllerSignInToEventRequest, + EventControllerRsvpForEventRequest, +} from './api/apis/EventApi'; +import { + MultipleEventResponse, + EventResponse, + EventRequest, + AppUserEventRequest, + AttendanceResponse, + RSVPResponse, +} from './api/models'; import ApiConfigStore from './ApiConfigStore'; import { Configuration } from './api/runtime'; @@ -17,3 +32,64 @@ export async function getEventById(eventID: number): Promise { }; return eventApi.eventControllerGetEvent(request); } + +export async function createEvent( + eventRequest: EventRequest +): Promise { + const apiConfig: Configuration = ApiConfigStore.getApiConfig(); + const eventApi: EventApi = new EventApi(apiConfig); + const request: EventControllerCreateEventRequest = { + eventRequest, + }; + + return eventApi.eventControllerCreateEvent(request); +} + +export async function updateEvent(eventID: number, eventRequest: EventRequest) { + const apiConfig: Configuration = ApiConfigStore.getApiConfig(); + const eventApi: EventApi = new EventApi(apiConfig); + const request: EventControllerUpdateEventRequest = { + eventID, + eventRequest, + }; + + return eventApi.eventControllerUpdateEvent(request); +} + +export async function deleteEvent(eventID: number): Promise { + const apiConfig: Configuration = ApiConfigStore.getApiConfig(); + const eventApi: EventApi = new EventApi(apiConfig); + const request: EventControllerDeleteEventRequest = { + eventID, + }; + + return eventApi.eventControllerDeleteEvent(request); +} + +export async function signInToEvent( + eventID: number, + appUserEventRequest: AppUserEventRequest +): Promise { + const apiConfig: Configuration = ApiConfigStore.getApiConfig(); + const eventApi: EventApi = new EventApi(apiConfig); + const request: EventControllerSignInToEventRequest = { + eventID, + appUserEventRequest, + }; + + return eventApi.eventControllerSignInToEvent(request); +} + +export async function rsvpToEvent( + eventID: number, + appUserEventRequest: AppUserEventRequest +): Promise { + const apiConfig: Configuration = ApiConfigStore.getApiConfig(); + const eventApi: EventApi = new EventApi(apiConfig); + const request: EventControllerRsvpForEventRequest = { + eventID, + appUserEventRequest, + }; + + return eventApi.eventControllerRsvpForEvent(request); +} diff --git a/src/services/api/.openapi-generator/FILES b/src/services/api/.openapi-generator/FILES index f962ca06..1f453ddc 100644 --- a/src/services/api/.openapi-generator/FILES +++ b/src/services/api/.openapi-generator/FILES @@ -1,16 +1,20 @@ -apis/EventApi.ts -apis/index.ts -index.ts -models/AppUserEventRequest.ts -models/AppUserEventResponse.ts -models/AppUserPKPayload.ts -models/AttendanceResponse.ts -models/BaseEventPayload.ts -models/EventAttendanceResponse.ts -models/EventRSVPResponse.ts -models/EventRequest.ts -models/EventResponse.ts -models/MultipleEventResponse.ts -models/RSVPResponse.ts -models/index.ts -runtime.ts +apis\EventApi.ts +apis\UserApi.ts +apis\index.ts +index.ts +models\AppUserEventRequest.ts +models\AppUserEventResponse.ts +models\AppUserInductionClass.ts +models\AppUserPKPayload.ts +models\AppUserProfileResponse.ts +models\AppUserRolesResponse.ts +models\AttendanceResponse.ts +models\BaseEventPayload.ts +models\EventAttendanceResponse.ts +models\EventRSVPResponse.ts +models\EventRequest.ts +models\EventResponse.ts +models\MultipleEventResponse.ts +models\RSVPResponse.ts +models\index.ts +runtime.ts diff --git a/src/services/api/apis/EventApi.ts b/src/services/api/apis/EventApi.ts index 7f134912..d03dc85e 100644 --- a/src/services/api/apis/EventApi.ts +++ b/src/services/api/apis/EventApi.ts @@ -77,6 +77,15 @@ export class EventApi extends runtime.BaseAPI { headerParameters['Content-Type'] = 'application/json'; + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = + typeof token === 'function' ? token('TokenAuth', []) : token; + + if (tokenString) { + headerParameters['Authorization'] = `Bearer ${tokenString}`; + } + } const response = await this.request({ path: `/api/events/`, method: 'POST', @@ -122,6 +131,15 @@ export class EventApi extends runtime.BaseAPI { const headerParameters: runtime.HTTPHeaders = {}; + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = + typeof token === 'function' ? token('TokenAuth', []) : token; + + if (tokenString) { + headerParameters['Authorization'] = `Bearer ${tokenString}`; + } + } const response = await this.request({ path: `/api/events/{eventID}`.replace( `{${'eventID'}}`, @@ -246,6 +264,15 @@ export class EventApi extends runtime.BaseAPI { headerParameters['Content-Type'] = 'application/json'; + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = + typeof token === 'function' ? token('TokenAuth', []) : token; + + if (tokenString) { + headerParameters['Authorization'] = `Bearer ${tokenString}`; + } + } const response = await this.request({ path: `/api/events/{eventID}/rsvp`.replace( `{${'eventID'}}`, @@ -296,6 +323,15 @@ export class EventApi extends runtime.BaseAPI { headerParameters['Content-Type'] = 'application/json'; + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = + typeof token === 'function' ? token('TokenAuth', []) : token; + + if (tokenString) { + headerParameters['Authorization'] = `Bearer ${tokenString}`; + } + } const response = await this.request({ path: `/api/events/{eventID}/signin`.replace( `{${'eventID'}}`, @@ -346,6 +382,15 @@ export class EventApi extends runtime.BaseAPI { headerParameters['Content-Type'] = 'application/json'; + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = + typeof token === 'function' ? token('TokenAuth', []) : token; + + if (tokenString) { + headerParameters['Authorization'] = `Bearer ${tokenString}`; + } + } const response = await this.request({ path: `/api/events/{eventID}`.replace( `{${'eventID'}}`, diff --git a/src/services/api/apis/UserApi.ts b/src/services/api/apis/UserApi.ts new file mode 100644 index 00000000..8444d877 --- /dev/null +++ b/src/services/api/apis/UserApi.ts @@ -0,0 +1,137 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * HKN API + * HKN API + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime'; +import { + AppUserProfileResponse, + AppUserProfileResponseFromJSON, + AppUserProfileResponseToJSON, + AppUserRolesResponse, + AppUserRolesResponseFromJSON, + AppUserRolesResponseToJSON, +} from '../models'; + +export interface UserControllerGetUserProfileRequest { + userID: number; +} + +export interface UserControllerGetUserRoleRequest { + userID: number; +} + +/** + * + */ +export class UserApi extends runtime.BaseAPI { + /** + * Get user profile + */ + async userControllerGetUserProfileRaw( + requestParameters: UserControllerGetUserProfileRequest + ): Promise> { + if ( + requestParameters.userID === null || + requestParameters.userID === undefined + ) { + throw new runtime.RequiredError( + 'userID', + 'Required parameter requestParameters.userID was null or undefined when calling userControllerGetUserProfile.' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/api/users/{userID}`.replace( + `{${'userID'}}`, + encodeURIComponent(String(requestParameters.userID)) + ), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }); + + return new runtime.JSONApiResponse(response, jsonValue => + AppUserProfileResponseFromJSON(jsonValue) + ); + } + + /** + * Get user profile + */ + async userControllerGetUserProfile( + requestParameters: UserControllerGetUserProfileRequest + ): Promise { + const response = await this.userControllerGetUserProfileRaw( + requestParameters + ); + return await response.value(); + } + + /** + * Get user role + */ + async userControllerGetUserRoleRaw( + requestParameters: UserControllerGetUserRoleRequest + ): Promise> { + if ( + requestParameters.userID === null || + requestParameters.userID === undefined + ) { + throw new runtime.RequiredError( + 'userID', + 'Required parameter requestParameters.userID was null or undefined when calling userControllerGetUserRole.' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = + typeof token === 'function' ? token('TokenAuth', []) : token; + + if (tokenString) { + headerParameters['Authorization'] = `Bearer ${tokenString}`; + } + } + const response = await this.request({ + path: `/api/users/{userID}/roles`.replace( + `{${'userID'}}`, + encodeURIComponent(String(requestParameters.userID)) + ), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }); + + return new runtime.JSONApiResponse(response, jsonValue => + AppUserRolesResponseFromJSON(jsonValue) + ); + } + + /** + * Get user role + */ + async userControllerGetUserRole( + requestParameters: UserControllerGetUserRoleRequest + ): Promise { + const response = await this.userControllerGetUserRoleRaw(requestParameters); + return await response.value(); + } +} diff --git a/src/services/api/apis/index.ts b/src/services/api/apis/index.ts index 614dfc9c..2c5754d1 100644 --- a/src/services/api/apis/index.ts +++ b/src/services/api/apis/index.ts @@ -1 +1,2 @@ export * from './EventApi'; +export * from './UserApi'; diff --git a/src/services/api/models/AppUserInductionClass.ts b/src/services/api/models/AppUserInductionClass.ts new file mode 100644 index 00000000..58b87eb7 --- /dev/null +++ b/src/services/api/models/AppUserInductionClass.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * HKN API + * HKN API + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AppUserInductionClass + */ +export interface AppUserInductionClass { + /** + * + * @type {string} + * @memberof AppUserInductionClass + */ + quarter: string; + /** + * + * @type {string} + * @memberof AppUserInductionClass + */ + name: string; + /** + * + * @type {string} + * @memberof AppUserInductionClass + */ + startDate: string; + /** + * + * @type {string} + * @memberof AppUserInductionClass + */ + endDate: string; +} + +export function AppUserInductionClassFromJSON( + json: any +): AppUserInductionClass { + return AppUserInductionClassFromJSONTyped(json, false); +} + +export function AppUserInductionClassFromJSONTyped( + json: any, + ignoreDiscriminator: boolean +): AppUserInductionClass { + if (json === undefined || json === null) { + return json; + } + return { + quarter: json['quarter'], + name: json['name'], + startDate: json['startDate'], + endDate: json['endDate'], + }; +} + +export function AppUserInductionClassToJSON( + value?: AppUserInductionClass | null +): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + quarter: value.quarter, + name: value.name, + startDate: value.startDate, + endDate: value.endDate, + }; +} diff --git a/src/services/api/models/AppUserProfileResponse.ts b/src/services/api/models/AppUserProfileResponse.ts new file mode 100644 index 00000000..b6cb0d7f --- /dev/null +++ b/src/services/api/models/AppUserProfileResponse.ts @@ -0,0 +1,107 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * HKN API + * HKN API + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import { + AppUserInductionClass, + AppUserInductionClassFromJSON, + AppUserInductionClassFromJSONTyped, + AppUserInductionClassToJSON, +} from './'; + +/** + * + * @export + * @interface AppUserProfileResponse + */ +export interface AppUserProfileResponse { + /** + * + * @type {string} + * @memberof AppUserProfileResponse + */ + firstName: string; + /** + * + * @type {string} + * @memberof AppUserProfileResponse + */ + lastName: string; + /** + * + * @type {string} + * @memberof AppUserProfileResponse + */ + email: string; + /** + * + * @type {string} + * @memberof AppUserProfileResponse + */ + major: string; + /** + * + * @type {string} + * @memberof AppUserProfileResponse + */ + graduationYear: string; + /** + * + * @type {AppUserInductionClass} + * @memberof AppUserProfileResponse + */ + inductionClass: AppUserInductionClass; +} + +export function AppUserProfileResponseFromJSON( + json: any +): AppUserProfileResponse { + return AppUserProfileResponseFromJSONTyped(json, false); +} + +export function AppUserProfileResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean +): AppUserProfileResponse { + if (json === undefined || json === null) { + return json; + } + return { + firstName: json['firstName'], + lastName: json['lastName'], + email: json['email'], + major: json['major'], + graduationYear: json['graduationYear'], + inductionClass: AppUserInductionClassFromJSON(json['inductionClass']), + }; +} + +export function AppUserProfileResponseToJSON( + value?: AppUserProfileResponse | null +): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + firstName: value.firstName, + lastName: value.lastName, + email: value.email, + major: value.major, + graduationYear: value.graduationYear, + inductionClass: AppUserInductionClassToJSON(value.inductionClass), + }; +} diff --git a/src/services/api/models/AppUserRolesResponse.ts b/src/services/api/models/AppUserRolesResponse.ts new file mode 100644 index 00000000..c2a10cb9 --- /dev/null +++ b/src/services/api/models/AppUserRolesResponse.ts @@ -0,0 +1,70 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * HKN API + * HKN API + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface AppUserRolesResponse + */ +export interface AppUserRolesResponse { + /** + * + * @type {string} + * @memberof AppUserRolesResponse + */ + role: AppUserRolesResponseRoleEnum; +} + +export function AppUserRolesResponseFromJSON(json: any): AppUserRolesResponse { + return AppUserRolesResponseFromJSONTyped(json, false); +} + +export function AppUserRolesResponseFromJSONTyped( + json: any, + ignoreDiscriminator: boolean +): AppUserRolesResponse { + if (json === undefined || json === null) { + return json; + } + return { + role: json['role'], + }; +} + +export function AppUserRolesResponseToJSON( + value?: AppUserRolesResponse | null +): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + role: value.role, + }; +} + +/** + * @export + * @enum {string} + */ +export enum AppUserRolesResponseRoleEnum { + Admin = 'admin', + Officer = 'officer', + Member = 'member', + Inductee = 'inductee', + Guest = 'guest', +} diff --git a/src/services/api/models/index.ts b/src/services/api/models/index.ts index a05471b3..e5581367 100644 --- a/src/services/api/models/index.ts +++ b/src/services/api/models/index.ts @@ -1,6 +1,9 @@ export * from './AppUserEventRequest'; export * from './AppUserEventResponse'; +export * from './AppUserInductionClass'; export * from './AppUserPKPayload'; +export * from './AppUserProfileResponse'; +export * from './AppUserRolesResponse'; export * from './AttendanceResponse'; export * from './BaseEventPayload'; export * from './EventAttendanceResponse'; From 1f3059e00152412d9941c32c967115a19ddbe598 Mon Sep 17 00:00:00 2001 From: Thai Date: Wed, 26 Aug 2020 17:29:43 -0700 Subject: [PATCH 2/3] Made changes based on review on PR #143 --- src/pages/App/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pages/App/index.js b/src/pages/App/index.js index eb015c50..e44b801f 100644 --- a/src/pages/App/index.js +++ b/src/pages/App/index.js @@ -29,6 +29,7 @@ import ApiConfigStore from '@Services/ApiConfigStore'; const INITIAL_STATES = { userClaims: null, + userToken: null, isLoading: true, }; @@ -52,11 +53,13 @@ class App extends React.Component { userId: claims.user_id, userRoles: getRolesFromClaims(claims), }, + userToken: token, isLoading: false, }); } else { this.setState({ userClaims: null, + userToken: null, isLoading: false, }); } @@ -64,11 +67,14 @@ class App extends React.Component { } setClaims = claims => { + const { userToken } = this.state; + this.setState({ userClaims: { userId: claims.user_id, userRoles: getRolesFromClaims(claims), }, + userToken, }); }; From 39eeaabed931e488c666d6b3ab3e4cde921f9311 Mon Sep 17 00:00:00 2001 From: Thai Date: Wed, 26 Aug 2020 17:56:30 -0700 Subject: [PATCH 3/3] Okay actual changes reflecting review on PR #143. --- src/pages/App/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/App/index.js b/src/pages/App/index.js index e44b801f..fcf00e8f 100644 --- a/src/pages/App/index.js +++ b/src/pages/App/index.js @@ -46,8 +46,6 @@ class App extends React.Component { const tokenResult = await user.getIdTokenResult(); const { claims, token } = tokenResult; - ApiConfigStore.setToken(token); - this.setState({ userClaims: { userId: claims.user_id, @@ -69,12 +67,13 @@ class App extends React.Component { setClaims = claims => { const { userToken } = this.state; + ApiConfigStore.setToken(userToken); + this.setState({ userClaims: { userId: claims.user_id, userRoles: getRolesFromClaims(claims), }, - userToken, }); };