-
Notifications
You must be signed in to change notification settings - Fork 402
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
1,062 additions
and
125 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
const statusCodes = { | ||
CONTINUE: 100, | ||
SWITCHING_PROTOCOLS: 101, | ||
PROCESSING: 102, | ||
EARLY_HINTS: 103, | ||
OK: 200, | ||
CREATED: 201, | ||
ACCEPTED: 202, | ||
NON_AUTHORITATIVE_INFORMATION: 203, | ||
NO_CONTENT: 204, | ||
RESET_CONTENT: 205, | ||
PARTIAL_CONTENT: 206, | ||
MULTI_STATUS: 207, | ||
ALREADY_REPORTED: 208, | ||
IM_USED: 226, | ||
MULTIPLE_CHOICES: 300, | ||
MOVED_PERMANENTLY: 301, | ||
FOUND: 302, | ||
SEE_OTHER: 303, | ||
NOT_MODIFIED: 304, | ||
USE_PROXY: 305, | ||
TEMPORARY_REDIRECT: 307, | ||
PERMANENT_REDIRECT: 308, | ||
BAD_REQUEST: 400, | ||
UNAUTHORIZED: 401, | ||
PAYMENT_REQUIRED: 402, | ||
FORBIDDEN: 403, | ||
NOT_FOUND: 404, | ||
METHOD_NOT_ALLOWED: 405, | ||
NOT_ACCEPTABLE: 406, | ||
PROXY_AUTHENTICATION_REQUIRED: 407, | ||
REQUEST_TIMEOUT: 408, | ||
CONFLICT: 409, | ||
GONE: 410, | ||
LENGTH_REQUIRED: 411, | ||
PRECONDITION_FAILED: 412, | ||
PAYLOAD_TOO_LARGE: 413, | ||
URI_TOO_LONG: 414, | ||
UNSUPPORTED_MEDIA_TYPE: 415, | ||
RANGE_NOT_SATISFIABLE: 416, | ||
EXPECTATION_FAILED: 417, | ||
I_M_A_TEAPOT: 418, | ||
MISDIRECTED_REQUEST: 421, | ||
UNPROCESSABLE_ENTITY: 422, | ||
LOCKED: 423, | ||
FAILED_DEPENDENCY: 424, | ||
TOO_EARLY: 425, | ||
UPGRADE_REQUIRED: 426, | ||
PRECONDITION_REQUIRED: 428, | ||
TOO_MANY_REQUESTS: 429, | ||
REQUEST_HEADER_FIELDS_TOO_LARGE: 431, | ||
UNAVAILABLE_FOR_LEGAL_REASONS: 451, | ||
INTERNAL_SERVER_ERROR: 500, | ||
NOT_IMPLEMENTED: 501, | ||
BAD_GATEWAY: 502, | ||
SERVICE_UNAVAILABLE: 503, | ||
GATEWAY_TIMEOUT: 504, | ||
HTTP_VERSION_NOT_SUPPORTED: 505, | ||
VARIANT_ALSO_NEGOTIATES: 506, | ||
INSUFFICIENT_STORAGE: 507, | ||
LOOP_DETECTED: 508, | ||
NOT_EXTENDED: 510, | ||
NETWORK_AUTHENTICATION_REQUIRED: 511, | ||
}; | ||
|
||
export default statusCodes; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { NextApiRequest, NextApiResponse } from 'next'; | ||
|
||
import validator from 'validator'; | ||
import { v4 as uuidv4 } from 'uuid'; | ||
import axios from 'axios'; | ||
|
||
import { UserModel } from '@/models/UserModel'; | ||
import statusCodes from '@/httpStatusCodes'; | ||
import connectMongo from '@/mongo'; | ||
|
||
let accessToken = process.env.ACCESS_TOKEN; | ||
const clientId = process.env.clientId; | ||
const clientSecret = process.env.clientSecret; | ||
const domain = process.env.DOMAIN; | ||
|
||
export const headers = { | ||
'Content-Type': 'application/json', | ||
Accept: 'application/json', | ||
Authorization: `Bearer ${accessToken}`, | ||
}; | ||
|
||
export const createUserWithAutoId = async (email: string) => { | ||
// Logic to create a new user with an autogenerated ID | ||
return UserModel.create({ _id: uuidv4(), email }); | ||
}; | ||
|
||
// Define separate email validation middleware | ||
export const emailValidator = async ( | ||
req: NextApiRequest, | ||
res: NextApiResponse, | ||
next: Function | ||
) => { | ||
const { email: emailBody } = req.body; | ||
const { email: emailQuery } = req.query; | ||
|
||
const isItInTheBody = | ||
typeof emailBody !== 'string' || !validator.isEmail(emailBody); | ||
const isItInQuery = | ||
typeof emailQuery !== 'string' || !validator.isEmail(emailQuery); | ||
|
||
if (isItInTheBody || isItInQuery) { | ||
return res.status(statusCodes.NOT_ACCEPTABLE).json({ | ||
message: 'Email is invalid', | ||
}); | ||
} else { | ||
await connectMongo(); | ||
next(); | ||
} | ||
}; | ||
|
||
export const getAccessToken = async () => { | ||
try { | ||
const response = await axios.post(`${domain}/oauth2/token`, null, { | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
params: { | ||
grant_type: 'client_credentials', | ||
client_id: clientId, | ||
client_secret: clientSecret, | ||
audience: `${domain}/api`, | ||
}, | ||
}); | ||
|
||
if (response.status !== 200) { | ||
throw new Error(`Couldn't get access token`); | ||
} | ||
|
||
return response.data.access_token; | ||
} catch (error) { | ||
console.error('An error occurred:', error); | ||
} | ||
}; | ||
|
||
export const getKindeUser = async (email: string) => { | ||
const response = await axios.get(`${domain}/api/v1/users?email=${email}`, { | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Accept: 'application/json', | ||
Authorization: `Bearer ${accessToken}`, | ||
}, | ||
}); | ||
let data; | ||
if (response.status !== 200) { | ||
const errorText = response.data; | ||
if (errorText.errors[1].code === 'TOKEN_INVALID') { | ||
const newAccessToken = await getAccessToken(); | ||
accessToken = newAccessToken; | ||
|
||
const response = await axios.get( | ||
`${domain}/api/v1/users?email=${email}`, | ||
{ | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Accept: 'application/json', | ||
Authorization: `Bearer ${newAccessToken}`, | ||
}, | ||
} | ||
); | ||
|
||
data = response.data; | ||
} else { | ||
console.log(errorText); | ||
throw new Error(`Couldn't get user from kinde`); | ||
} | ||
} else { | ||
data = response.data; | ||
} | ||
return data; | ||
}; | ||
|
||
export const createUserWithId = async (email: string, id: string) => { | ||
// Logic to create a new user with a provided ID | ||
const getUser = await getKindeUser(email); | ||
const doesUserExist = getUser.users ? true : false; | ||
|
||
if (doesUserExist) { | ||
return UserModel.create({ _id: id, email }); | ||
} | ||
|
||
const inputBody = { | ||
identities: [ | ||
{ | ||
type: 'email', | ||
details: { | ||
email: email, | ||
}, | ||
}, | ||
], | ||
}; | ||
const response = await axios.post(`${domain}/api/v1/user`, inputBody, { | ||
headers: headers, | ||
}); | ||
|
||
if (response.status !== 200) { | ||
const errorText = response.data; | ||
if (errorText.errors[1].code === 'TOKEN_INVALID') { | ||
const newAccessToken = await getAccessToken(); | ||
accessToken = newAccessToken; | ||
|
||
await axios.post(`${domain}/api/v1/user`, inputBody, { | ||
headers: headers, | ||
}); | ||
} else { | ||
throw new Error(`Couldn't add user to kinde`); | ||
} | ||
} | ||
|
||
return UserModel.create({ _id: id, email }); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import mongoose, { Connection, Error, Mongoose } from 'mongoose'; | ||
import { init } from './lib/lib'; | ||
|
||
// Initialize variables to store the MongoDB connection and Mongoose instance. | ||
let connection: Connection | null = null; | ||
let mongooseInstance: Mongoose | null = null; | ||
|
||
// Retrieve the MongoDB connection string from environment variables. | ||
const connectionString = process.env.MongoDB_URL; | ||
|
||
// Async function to establish and return a MongoDB connection. | ||
const connectMongo = async (): Promise<Connection> => { | ||
// Check if the connection string is defined in the environment. | ||
if (!connectionString) { | ||
throw new Error('Connection String is missing, add it to the env file'); | ||
} | ||
|
||
// If a connection already exists, return it. | ||
if (connection) { | ||
return connection; | ||
} | ||
|
||
try { | ||
// Define connection options for MongoDB. | ||
const options = { | ||
autoIndex: true, | ||
family: 4, | ||
maxPoolSize: 10, | ||
useNewUrlParser: true, | ||
useUnifiedTopology: true, | ||
}; | ||
|
||
mongoose.set('strictQuery', false); | ||
|
||
// Connect to MongoDB and store the Mongoose instance. | ||
mongooseInstance = await mongoose.connect(connectionString, options); | ||
|
||
// Get the MongoDB connection from the Mongoose instance. | ||
connection = mongooseInstance.connection; | ||
|
||
init() | ||
.then(done => console.log(`sorted the search`)) | ||
.catch(error => console.log(error)); | ||
|
||
// Log a successful database connection. | ||
console.log('DB connection successful:', connection.name); | ||
|
||
// Return the MongoDB connection. | ||
return connection; | ||
} catch (error) { | ||
// Handle any errors that occur during the connection process. | ||
const errorMessage = error as Error; | ||
console.error('DB connection failed:', errorMessage.message); | ||
|
||
// Re-throw the error to signal the failure. | ||
throw error; | ||
} | ||
}; | ||
|
||
// Export the connectMongo function for use in other parts of your application. | ||
export default connectMongo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.