Skip to content

Commit 3e940cf

Browse files
committed
Convert CredentialTokens from model to raw
1 parent d18ea46 commit 3e940cf

File tree

8 files changed

+59
-49
lines changed

8 files changed

+59
-49
lines changed

app/cas/server/cas_server.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import CAS from 'cas';
1010

1111
import { logger } from './cas_rocketchat';
1212
import { settings } from '../../settings';
13-
import { Rooms, CredentialTokens } from '../../models/server';
13+
import { Rooms } from '../../models/server';
14+
import { CredentialTokens } from '../../models/server/raw';
1415
import { _setRealName } from '../../lib';
1516
import { createRoom } from '../../lib/server/functions/createRoom';
1617

@@ -43,7 +44,7 @@ const casTicket = function(req, token, callback) {
4344
service: `${ appUrl }/_cas/${ token }`,
4445
});
4546

46-
cas.validate(ticketId, Meteor.bindEnvironment(function(err, status, username, details) {
47+
cas.validate(ticketId, Meteor.bindEnvironment(async function(err, status, username, details) {
4748
if (err) {
4849
logger.error(`error when trying to validate: ${ err.message }`);
4950
} else if (status) {
@@ -54,11 +55,11 @@ const casTicket = function(req, token, callback) {
5455
if (details && details.attributes) {
5556
_.extend(user_info, { attributes: details.attributes });
5657
}
57-
CredentialTokens.create(token, user_info);
58+
await CredentialTokens.create(token, user_info);
5859
} else {
5960
logger.error(`Unable to validate ticket: ${ ticketId }`);
6061
}
61-
// logger.debug("Receveied response: " + JSON.stringify(details, null , 4));
62+
// logger.debug("Received response: " + JSON.stringify(details, null , 4));
6263

6364
callback();
6465
}));
@@ -114,7 +115,8 @@ Accounts.registerLoginHandler(function(options) {
114115
return undefined;
115116
}
116117

117-
const credentials = CredentialTokens.findOneById(options.cas.credentialToken);
118+
// TODO: Sync wrapper due to the chain conversion to async models
119+
const credentials = Promise.await(CredentialTokens.findOneNotExpiredById(options.cas.credentialToken));
118120
if (credentials === undefined) {
119121
throw new Meteor.Error(Accounts.LoginCancelledError.numericError,
120122
'no matching login attempt found');

app/meteor-accounts-saml/server/lib/SAML.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import fiber from 'fibers';
88
import { escapeRegExp, escapeHTML } from '@rocket.chat/string-helpers';
99

1010
import { settings } from '../../../settings/server';
11-
import { Users, Rooms, CredentialTokens } from '../../../models/server';
11+
import { Users, Rooms } from '../../../models/server';
12+
import { CredentialTokens } from '../../../models/server/raw';
1213
import { IUser } from '../../../../definition/IUser';
1314
import { IIncomingMessage } from '../../../../definition/IIncomingMessage';
1415
import { saveUserIdentity, createRoom, generateUsernameSuggestion, addUserToRoom } from '../../../lib/server/functions';
@@ -55,20 +56,20 @@ export class SAML {
5556
}
5657
}
5758

58-
public static hasCredential(credentialToken: string): boolean {
59-
return CredentialTokens.findOneById(credentialToken) != null;
59+
public static async hasCredential(credentialToken: string): Promise<boolean> {
60+
return await CredentialTokens.findOneNotExpiredById(credentialToken) != null;
6061
}
6162

62-
public static retrieveCredential(credentialToken: string): Record<string, any> | undefined {
63+
public static async retrieveCredential(credentialToken: string): Promise<Record<string, any> | undefined> {
6364
// The credentialToken in all these functions corresponds to SAMLs inResponseTo field and is mandatory to check.
64-
const data = CredentialTokens.findOneById(credentialToken);
65+
const data = await CredentialTokens.findOneNotExpiredById(credentialToken);
6566
if (data) {
6667
return data.userInfo;
6768
}
6869
}
6970

70-
public static storeCredential(credentialToken: string, loginResult: object): void {
71-
CredentialTokens.create(credentialToken, loginResult);
71+
public static async storeCredential(credentialToken: string, loginResult: {profile: Record<string, any>}): Promise<void> {
72+
await CredentialTokens.create(credentialToken, loginResult);
7273
}
7374

7475
public static insertOrUpdateSAMLUser(userObject: ISAMLUser): {userId: string; token: string} {
@@ -380,7 +381,7 @@ export class SAML {
380381
private static processValidateAction(req: IIncomingMessage, res: ServerResponse, service: IServiceProviderOptions, _samlObject: ISAMLAction): void {
381382
const serviceProvider = new SAMLServiceProvider(service);
382383
SAMLUtils.relayState = req.body.RelayState;
383-
serviceProvider.validateResponse(req.body.SAMLResponse, (err, profile/* , loggedOut*/) => {
384+
serviceProvider.validateResponse(req.body.SAMLResponse, async (err, profile/* , loggedOut*/) => {
384385
try {
385386
if (err) {
386387
SAMLUtils.error(err);
@@ -400,7 +401,7 @@ export class SAML {
400401
profile,
401402
};
402403

403-
this.storeCredential(credentialToken, loginResult);
404+
await this.storeCredential(credentialToken, loginResult);
404405
const url = `${ Meteor.absoluteUrl('home') }?saml_idp_credentialToken=${ credentialToken }`;
405406
res.writeHead(302, {
406407
Location: url,

app/meteor-accounts-saml/server/loginHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Accounts.registerLoginHandler('saml', function(loginRequest) {
1717
return undefined;
1818
}
1919

20-
const loginResult = SAML.retrieveCredential(loginRequest.credentialToken);
20+
const loginResult = Promise.await(SAML.retrieveCredential(loginRequest.credentialToken));
2121
SAMLUtils.log({ msg: 'RESULT', loginResult });
2222

2323
if (!loginResult) {

app/models/server/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import CustomUserStatus from './models/CustomUserStatus';
1818
import Imports from './models/Imports';
1919
import Integrations from './models/Integrations';
2020
import IntegrationHistory from './models/IntegrationHistory';
21-
import CredentialTokens from './models/CredentialTokens';
2221
import EmojiCustom from './models/EmojiCustom';
2322
import OAuthApps from './models/OAuthApps';
2423
import SmarshHistory from './models/SmarshHistory';
@@ -65,7 +64,6 @@ export {
6564
Imports,
6665
Integrations,
6766
IntegrationHistory,
68-
CredentialTokens,
6967
EmojiCustom,
7068
OAuthApps,
7169
SmarshHistory,

app/models/server/models/CredentialTokens.js

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { BaseRaw, IndexSpecification } from './BaseRaw';
2+
import { ICredentialToken as T } from '../../../../definition/ICredentialToken';
3+
4+
export class CredentialTokensRaw extends BaseRaw<T> {
5+
protected indexes: IndexSpecification[] = [
6+
{ key: { expireAt: 1 }, sparse: true, expireAfterSeconds: 0 },
7+
]
8+
9+
async create(_id: string, userInfo: T['userInfo']): Promise<T> {
10+
const validForMilliseconds = 60000; // Valid for 60 seconds
11+
const token = {
12+
_id,
13+
userInfo,
14+
expireAt: new Date(Date.now() + validForMilliseconds),
15+
};
16+
17+
await this.insertOne(token);
18+
return token;
19+
}
20+
21+
findOneNotExpiredById(_id: string): Promise<T | null> {
22+
const query = {
23+
_id,
24+
expireAt: { $gt: new Date() },
25+
};
26+
27+
return this.findOne(query);
28+
}
29+
}

app/models/server/raw/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import { ImportDataRaw } from './ImportData';
7272
import { OEmbedCacheRaw } from './OEmbedCache';
7373
import { InvitesRaw } from './Invites';
7474
import { AnalyticsRaw } from './Analytics';
75+
import { CredentialTokensRaw } from './CredentialTokens';
7576

7677
const trashCollection = trash.rawCollection();
7778

@@ -117,6 +118,7 @@ export const Invites = new InvitesRaw(db.collection(`${ prefix }invites`), trash
117118
export const ServerEvents = new ServerEventsRaw(db.collection(`${ prefix }server_events`), trashCollection);
118119
export const EmailInbox = new EmailInboxRaw(db.collection(`${ prefix }email_inbox`), trashCollection);
119120
export const Analytics = new AnalyticsRaw(db.collection(`${ prefix }analytics`, { readPreference: readSecondaryPreferred(db) }), trashCollection);
121+
export const CredentialTokens = new CredentialTokensRaw(db.collection(`${ prefix }credential_tokens`), trashCollection);
120122

121123
const map = {
122124
[Messages.col.collectionName]: MessagesModel,

definition/ICredentialToken.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface ICredentialToken {
2+
_id: string;
3+
4+
userInfo: {
5+
username?: string;
6+
attributes?: any;
7+
profile?: Record<string, any>;
8+
};
9+
expireAt: Date;
10+
}

0 commit comments

Comments
 (0)