Skip to content

Commit

Permalink
Merge branch 'user-router-cleanup' into frontend-keys
Browse files Browse the repository at this point in the history
  • Loading branch information
emlun committed Sep 7, 2023
2 parents 552bdb1 + 3c4bff4 commit 7c02d0e
Show file tree
Hide file tree
Showing 20 changed files with 1,207 additions and 230 deletions.
10 changes: 9 additions & 1 deletion config/config.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,13 @@ export = {
password: undefined
},
walletClientUrl: "WALLET_CLIENT_URL",
webauthn: {
attestation: "direct",
origin: "WEBAUTHN_ORIGIN",
rp: {
id: "WEBAUTHN_RP_ID",
name: "Digital Wallet demo",
},
},
alg: "ES256",
}
}
11 changes: 4 additions & 7 deletions development.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@ COPY package.json yarn.lock .npmrc ./
# RUN apt update -y && apt install python3 -y

RUN mkdir -p node_modules
COPY --chown=node:node . .
RUN yarn cache clean && yarn install --frozen-lockfile


# Copy the rest of the application code to the container

ENV NODE_ENV development

RUN mkdir -p dist


RUN chown -R node:node /home/node/app/node_modules
RUN chown -R node:node /home/node/app/dist
USER node
CMD ["yarn", "dev"]
CMD ["yarn", "dev"]

# Copy the rest of the application code to the container
COPY --chown=node:node . .
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rm -rf dist && npx tsc",
"dev": "nodemon --config nodemon.json --exec \"npx tsc && yarn start\"",
"start": "node -r source-map-support/register dist/src/app.js"
"start": "node -r source-map-support/register dist/src/app.js",
"typeorm": "typeorm-ts-node-commonjs -d src/AppDataSource.ts",
"typeorm-raw": "typeorm-ts-node-commonjs"
},
"keywords": [],
"author": "",
"description": "",
"dependencies": {
"@gunet/ssi-sdk": "^1.0.0",
"@simplewebauthn/server": "^7.4.0",
"ajv": "^8.12.0",
"apn": "^2.2.0",
"axios": "^0.27.2",
Expand All @@ -36,9 +39,11 @@
"sequelize": "^6.29.3",
"ts-results": "^3.3.0",
"typeorm": "^0.3.9",
"uuid": "^9.0.0",
"zod": "^3.21.4"
},
"devDependencies": {
"@simplewebauthn/typescript-types": "^7.4.0",
"@types/body-parser": "^1.19.2",
"@types/cookie-parser": "^1.4.3",
"@types/cors": "^2.8.12",
Expand All @@ -47,8 +52,10 @@
"@types/node": "^18.7.17",
"@types/node-fetch": "^2.6.4",
"@types/randomstring": "^1.1.8",
"@types/uuid": "^9.0.2",
"nodemon": "^2.0.19",
"source-map-support": "^0.5.21",
"ts-node": "^10.9.1",
"typescript": "^4.8.3"
}
}
64 changes: 32 additions & 32 deletions src/AppDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,43 @@ import config from "../config";

// Initialize DB connection
const AppDataSource: DataSource = new DataSource({
type: "mysql",
host: config.db.host,
port: config.db.port,
username: config.db.username,
password: config.db.password,
database: config.db.dbname,
entities: [__dirname + "/entities/*.entity.{js,ts}"],
synchronize: true
type: "mysql",
host: config.db.host,
port: config.db.port,
username: config.db.username,
password: config.db.password,
database: config.db.dbname,
entities: [__dirname + "/entities/*.entity.{js,ts}"],
synchronize: true
});

(async function initDataSource() {
let connected = false;
let connected = false;

console.log("Connecting with DB...");
await AppDataSource.initialize()
.then(() => {
console.log("App Data Source has been initialized!");
connected = true;
})
.catch((err) => {
console.error("Error during Data Source initialization", err);
});
console.log("Connecting with DB...");
await AppDataSource.initialize()
.then(() => {
console.log("App Data Source has been initialized!");
connected = true;
})
.catch((err) => {
console.error("Error during Data Source initialization", err);
});

// if not connected, then retry in loop
while (!connected) {
await new Promise((resolve) => setTimeout(resolve, 3000)).then(async () => {
await AppDataSource.initialize()
.then(() => {
console.log("App Data Source has been initialized!");
connected = true;
})
.catch((err) => {
console.error("Error during Data Source initialization", err);
});
});
}
// if not connected, then retry in loop
while (!connected) {
await new Promise((resolve) => setTimeout(resolve, 3000)).then(async () => {
await AppDataSource.initialize()
.then(() => {
console.log("App Data Source has been initialized!");
connected = true;
})
.catch((err) => {
console.error("Error during Data Source initialization", err);
});
});
}
})();


export default AppDataSource;
export default AppDataSource;
3 changes: 2 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import { issuanceRouter } from './routers/issuance.router';
import { storageRouter } from './routers/storage.router';
import { presentationRouter } from './routers/presentation.router';
import { legalPersonRouter } from './routers/legal_person.router';
import { reviverTaggedBase64UrlToBuffer } from './util/util';

const app: Express = express();
// __dirname is "/path/to/dist/src"

app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(bodyParser.json({ reviver: reviverTaggedBase64UrlToBuffer }));

app.use(express.static('public'));
// __dirname is "/path/to/dist/src"
Expand Down
10 changes: 6 additions & 4 deletions src/entities/LegalPerson.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ class LegalPersonEntity {
did: string = "";


@Column({ nullable: true })
// Explicit default to workaround a bug in typeorm: https://github.com/typeorm/typeorm/issues/3076#issuecomment-703128687
@Column({ nullable: true, default: () => "NULL" })
client_id: string = "";

@Column({ nullable: true })

// Explicit default to workaround a bug in typeorm: https://github.com/typeorm/typeorm/issues/3076#issuecomment-703128687
@Column({ nullable: true, default: () => "NULL" })
client_secret: string = "";
}

Expand Down Expand Up @@ -196,4 +198,4 @@ export {
getLegalPersonByDID,
getAllLegalPersonsDIDs,
getLegalPersonByUrl
}
}
107 changes: 107 additions & 0 deletions src/entities/WebauthnChallenge.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { Err, Ok, Result } from "ts-results";
import { Entity, PrimaryColumn, Column, Repository} from "typeorm"
import AppDataSource from "../AppDataSource";
import crypto from "node:crypto";
@Entity({ name: "webauthn_challenge" })
class WebauthnChallengeEntity {
@PrimaryColumn()
id: string;

@Column({ nullable: false})
type: string;

// Explicit default to workaround a bug in typeorm: https://github.com/typeorm/typeorm/issues/3076#issuecomment-703128687
@Column({ nullable: true, default: () => "NULL" })
userHandle?: string;

@Column({ nullable: false })
challenge: Buffer;

// Explicit default to workaround a bug in typeorm: https://github.com/typeorm/typeorm/issues/3076#issuecomment-703128687
@Column({ nullable: true, default: () => "NULL" })
prfSalt: Buffer;

@Column({ type: "datetime", nullable: false })
createTime: Date;
}

const TIMEOUT_MILLISECONDS = 15 * 60 * 1000;

type CreatedChallenge = {
id: string;
userHandle?: string;
challenge: Buffer;
prfSalt?: Buffer;
}

enum ChallengeErr {
NOT_EXISTS = "NOT_EXISTS",
DB_ERR = "DB_ERR",
EXPIRED = "EXPIRED",
}

const challengeRepository: Repository<WebauthnChallengeEntity> = AppDataSource.getRepository(WebauthnChallengeEntity);


async function createChallenge(type: "create" | "get", userHandle?: string, prfSalt?: Buffer): Promise<Result<CreatedChallenge, ChallengeErr>> {
try {
const returnData = {
userHandle,
prfSalt,
id: crypto.randomUUID(),
challenge: crypto.randomBytes(32),
};

const entity = challengeRepository.create({
...returnData,
type,
createTime: new Date(),
});
await challengeRepository.save(entity);

return Ok(returnData);
}
catch (e) {
console.log(e);
return Err(ChallengeErr.DB_ERR);
}
}

async function popChallenge(id: string): Promise<Result<WebauthnChallengeEntity, ChallengeErr>> {
return await challengeRepository.manager.transaction(async (manager) => {
try {
const res = await manager.findOne(WebauthnChallengeEntity, { where: { id } });

if (!res) {
return Err(ChallengeErr.NOT_EXISTS);
}

const timeoutThreshold = Date.now() - TIMEOUT_MILLISECONDS;

if (res.createTime.getTime() > timeoutThreshold) {
await manager.delete(WebauthnChallengeEntity, { id });
return Ok(res);

} else {
await manager
.createQueryBuilder()
.delete()
.from(WebauthnChallengeEntity)
.where("createTime <= :timeoutThreshold", { timeoutThreshold })
.execute();
return Err(ChallengeErr.EXPIRED);
}
}
catch (e) {
console.log(e);
return Err(ChallengeErr.DB_ERR);
}
});
}

export {
WebauthnChallengeEntity,
ChallengeErr,
createChallenge,
popChallenge,
}
Loading

0 comments on commit 7c02d0e

Please sign in to comment.