// frontend/main.js
router.beforeEach((to, from, next) => {
if (DEV) {
next();
} else {
checkLoginStatus(to, next);
}
});
// src/router/guards.js
const loginIfToken = async () => {
const sessionData = await authenticator.verifySessionCookie();
if (
sessionData?.profileId &&
sessionData?.sessionToken &&
!currentProfile.isLoggedIn
) {
await currentProfile.login(
sessionData.profileId,
WaveUI.instance.notify,
sessionData.sessionToken,
);
}
};
// src/services/auth.service.js
async verifySessionCookie() {
const validatedToken = await this.validateSession()
if (validatedToken.error)
return console.error('ERROR :=>', validatedToken.error)
return validatedToken
}
// src/services/auth.service.js
async validateSession() {
const hashedSessionToken = this.grabStoredSessionToken()
let validation
try {
validation = await db.post(
'/user/validate-session',
hashedSessionToken,
true,
)
} catch (error) {
console.error(error)
}
console.log('validatedSession :>> ', validation)
return validation
}
// src/services/auth.service.js
grabStoredSessionToken(cookieKey = 'siimee_session') {
const cookies = document.cookie.split('; ').reduce((prev, current) => {
const [name, ...value] = current.split('=')
prev[name] = value.join('=')
return prev
}, {})
if (!cookies[cookieKey])
return console.warn(
'WARNING :=> accessToken is not defined; There was problem with session cookie you are not logged in.',
)
return cookies[cookieKey]
}
// src/services/auth.service.js
async validateSession() {
const hashedSessionToken = this.grabStoredSessionToken()
let validation
try {
validation = await db.post(
'/user/validate-session',
hashedSessionToken,
true,
)
} catch (error) {
console.error(error)
}
console.log('validatedSession :>> ', validation)
return validation
}
// backend/lib/routes/user/validate-session.js
const validatedSessionToken = userService.validateSession(hashedSessionToken);
// backend/lib/services/user.js, line 255
validateSession(hashedSessionToken) {
const userSession = this.activeSessions[hashedSessionToken]
if (!userSession) {
throw new Error(
'hashedSessionToken not in activeSessions registry!',
)
}
if (!userSession.emailWasRespondedTo) {
throw new Error('email was never responded to!')
}
const sessionToken = userSession.sessionToken
const sessionTokenIsValid = this.validateToken(sessionToken)
return {
...sessionTokenIsValid.payload,
sessionToken: this.activeSessions[hashedSessionToken].sessionToken,
}
}
// backend/lib/services/user.js, line 241
validateToken(token) {
const key = this.server.registrations['main-app-plugin'].options.jwtKey
try {
return JWT.verify(token, key)
} catch (err) {
return { payload: null, message: err.message }
}
}
// backend/server/manifest.js, line 72
options: {
jwtKey: {
$filter: 'NODE_ENV',
$default: {
$param: 'APP_SECRET',
$default: 'app-secret',
},
// Use .env file in production
production: {
$param: 'APP_SECRET',
},
},
}
The JWT, from the ‘jsonwebtoken’ package is used to verify the token passed as well as the key. Should it fail, the return value of { payload: null, message: err.message } is returned instead.
Returning back to the validateSession(hashedSessionToken) in the services/user.js, we then proceed to destructure the return value of this sessionToken’s payload, as well as the sessionToken from this.activeSession[hashedSessionToken] object.
// backend/lib/services/user.js, line 265
const sessionToken = userSession.sessionToken;
const sessionTokenIsValid = this.validateToken(sessionToken);
return {
...sessionTokenIsValid.payload,
sessionToken: this.activeSessions[hashedSessionToken].sessionToken,
};
// backend/lib/routes/user/validate-session.js, line 36
const user = await userService.findByUserEmail(validatedSessionToken.email);
// backend/lib/services/user.js, line 104
async findByUserEmail(userEmail, txn) {
const { User } = this.server.models()
const user = await User.query(txn)
.throwIfNotFound()
.first()
.where({ user_email: userEmail })
return user
}
// backend/lib/routes/user/validate-session.js, line 39
const type = user.is_poster === 1 ? "poster" : "seeker";
// backend/lib/routes/user/validate-session.js, line 40
const profiles = await profileService.getCompleteProfilesFor(
user.user_id,
type,
);
// backend/lib/services/profile/index.js, line 98
async getCompleteProfilesFor(userId, type) {
const { Profile } = this.server.models()
await this._setTagLookup()
const dedupedProfileIds = await this._getProfileIdsForUserId(userId)
const profilesEntries = await Profile.query()
.whereIn('profile_id', dedupedProfileIds)
.withGraphFetched('tags')
.withGraphFetched('responses')
.withGraphFetched('user')
return profiler.makeCompleteFromProfileEntries(
profilesEntries,
type,
this.tagLookup,
)
}
// backend/lib/routes/user/validate-session.js, line 45
const profileId = profiles[0].profile_id;
// backend/lib/routes/user/validate-session.js, line 46
return {
ok: true,
handler: pluginConfig.handlerType,
data: {
...validatedSessionToken,
profileId: profileId,
},
};
// src/services/auth.service.js, line 20
async validateSession() {
const hashedSessionToken = this.grabStoredSessionToken()
let validation
try {
validation = await db.post(
'/user/validate-session',
hashedSessionToken,
true,
)
} catch (error) {
console.error(error)
}
console.log('validatedSession :>> ', validation)
return validation
}
// src/router/guards.js, line 17
const loginIfToken = async () => {
const sessionData = await authenticator.verifySessionCookie();
if (
sessionData?.profileId &&
sessionData?.sessionToken &&
!currentProfile.isLoggedIn
) {
await currentProfile.login(
sessionData.profileId,
WaveUI.instance.notify,
sessionData.sessionToken,
);
}
};
// src/router/guards.js, line 34
log(destination);
// src/router/guards.js, line 6
async function log(to) {
if (!currentProfile.isLoggedIn || !currentProfile.isComplete) {
console.info(
`[Guard Status debug]: Profile: ${currentProfile.id.value} | Login: ${currentProfile.isLoggedIn} | Complete: ${currentProfile.isComplete}`,
);
}
console.info("[Guard Status debug]: being routed to:", to.fullPath);
}