Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: set strictnullchecks = true #1422

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@typescript-eslint/consistent-type-assertions": 0,
"@typescript-eslint/no-dynamic-delete": 0,
"@typescript-eslint/prefer-nullish-coalescing": 0,
"@typescript-eslint/unbound-method": 0
"@typescript-eslint/unbound-method": 0,
"@typescript-eslint/no-non-null-assertion": "off"
}
}
19 changes: 11 additions & 8 deletions src/DataProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Maintenance, type MaintenanceEvent } from './stateMachines/maintenance/
import { Activation, type ActivationEvent } from './stateMachines/activation.js'
import ClientResponseMsg from './utils/ClientResponseMsg.js'
import { parseChunkedMessage } from './utils/parseChunkedMessage.js'
import { UNEXPECTED_PARSE_ERROR } from './utils/constants.js'
import { UNEXPECTED_PARSE_ERROR, type UnexpectedParseError } from './utils/constants.js'
import { SyncTimeEventType } from './stateMachines/maintenance/syncTime.js'
import { ChangePasswordEventType } from './stateMachines/maintenance/changePassword.js'
import { SyncHostNameEventType } from './stateMachines/maintenance/syncHostName.js'
Expand All @@ -40,7 +40,7 @@ export class DataProcessor {
*/
async processData (message: WebSocket.Data, clientId: string): Promise<ClientMsg | null> {
try {
let clientMsg: ClientMsg = null
let clientMsg: ClientMsg

try {
clientMsg = this.validator.parseClientMsg(message, clientId)
Expand Down Expand Up @@ -77,6 +77,7 @@ export class DataProcessor {
ClientResponseMsg.get(clientId, null, 'error', 'failed', 'request failed')
}
}
return null
}

async activateDevice (clientMsg: ClientMsg, clientId: string, activation: Activation = new Activation()): Promise<void> {
Expand Down Expand Up @@ -104,7 +105,7 @@ export class DataProcessor {
async handleResponse (clientMsg: ClientMsg, clientId: string): Promise<void> {
const clientObj = devices[clientId]
let resolveValue = null
let rejectValue = null
let rejectValue: UnexpectedParseError | HttpZResponseModel | null = null
let statusCode = -1
try {
const { parse } = pkg
Expand All @@ -124,10 +125,12 @@ export class DataProcessor {
rejectValue = new UNEXPECTED_PARSE_ERROR()
}
if (clientObj.pendingPromise != null) {
if (resolveValue) {
clientObj.resolve(resolveValue)
} else {
clientObj.reject(rejectValue)
if (clientObj.resolve && clientObj.reject) {
if (resolveValue) {
clientObj.resolve(resolveValue)
} else {
clientObj.reject(rejectValue)
}
}
}
this.logger.debug(`Device ${clientId}` +
Expand Down Expand Up @@ -177,7 +180,7 @@ export class DataProcessor {
return mEvent
}

setConnectionParams (clientId: string, username: string = null, password: string = null, uuid: string = null): void {
setConnectionParams (clientId: string, username: string | null = null, password: string | null = null, uuid: string | null = null): void {
const clientObj = devices[clientId]
clientObj.connectionParams = {
port: 16992,
Expand Down
6 changes: 3 additions & 3 deletions src/DomainCredentialManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import { type ISecretManagerService, type CertCredentials } from './interfaces/I
export class DomainCredentialManager implements IDomainCredentialManager {
private readonly amtDomains: IDomainsTable
private readonly logger: ILogger
private readonly secretsManager: ISecretManagerService = null
private readonly secretsManager: ISecretManagerService | null = null

constructor (logger: ILogger, amtDomains: IDomainsTable, secretsManager?: ISecretManagerService) {
this.amtDomains = amtDomains
this.logger = logger
this.secretsManager = secretsManager
this.secretsManager = secretsManager ?? null
}

/**
Expand All @@ -26,7 +26,7 @@ export class DomainCredentialManager implements IDomainCredentialManager {
* @param {string} tenantId
* @returns {AMTDomain} returns domain object
*/
async getProvisioningCert (domainSuffix: string, tenantId: string): Promise<AMTDomain> {
async getProvisioningCert (domainSuffix: string, tenantId: string): Promise<AMTDomain | null> {
const domain = await this.amtDomains.getDomainByDomainSuffix(domainSuffix, tenantId)
this.logger.debug(`domain : ${JSON.stringify(domain)}`)

Expand Down
2 changes: 1 addition & 1 deletion src/HttpHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,6 @@ it('should return a null when no xml is passed to wrap a WSMan request', async (
username: 'admin',
password: 'P@ssw0rd'
}
const result = httpHandler.wrapIt(null, connectionParams)
const result = httpHandler.wrapIt(null as any, connectionParams)
expect(result).toBe(null)
})
6 changes: 3 additions & 3 deletions src/HttpHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class HttpHandler {
this.logger = new Logger('HttpHandler')
}

wrapIt (data: string, connectionParams: connectionParams): string {
wrapIt (data: string, connectionParams: connectionParams): string | null {
try {
const url = '/wsman'
const action = 'POST'
Expand All @@ -34,7 +34,7 @@ export class HttpHandler {
}
if (connectionParams.digestChallenge != null) {
// Prepare an Authorization request header from the 401 unauthorized response from AMT
let responseDigest = null
let responseDigest: string | null = null
// console nonce should be a unique opaque quoted string
connectionParams.consoleNonce = Math.random().toString(36).substring(7)
const nc = ('00000000' + (this.nonceCounter++).toString(16)).slice(-8)
Expand Down Expand Up @@ -77,7 +77,7 @@ export class HttpHandler {

// Prepares Authorization Request Header
digestIt (params: object): string {
const paramNames = []
const paramNames: string[] = []
for (const i in params) {
paramNames.push(i)
}
Expand Down
28 changes: 5 additions & 23 deletions src/Index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
import { Configurator } from './Configurator.js'
import { Environment } from './utils/Environment.js'
import { type RPSConfig } from './models/index.js'
import { parseValue } from './utils/parseEnvValue.js'
import routes from './routes/index.js'
import rc from 'rc'
import { MqttProvider } from './utils/MqttProvider.js'
import { DbCreatorFactory } from './factories/DbCreatorFactory.js'
import { backOff } from 'exponential-backoff'
Expand All @@ -30,22 +28,6 @@
const __dirname = fileURLToPath(new URL('.', import.meta.url))
const log = new Logger('Index')

// To merge ENV variables. consider after lowercasing ENV since our config keys are lowercase
process.env = Object.keys(process.env)
.reduce((destination, key) => {
destination[key.toLowerCase()] = parseValue(process.env[key])
return destination
}, {})

// build config object
const config: RPSConfig = rc('rps')
config.delay_activation_sync = config.delay_timer * 1000
config.delay_setup_and_config_sync = 5000
config.delay_tls_put_data_sync = 5000
log.silly(`config: ${JSON.stringify(config, null, 2)}`)

Environment.Config = config

const app = express()
app.use(cors())
app.use(express.urlencoded())
Expand Down Expand Up @@ -75,7 +57,7 @@
const serverForEnterpriseAssistant: WSEnterpriseAssistantListener = new WSEnterpriseAssistantListener(new Logger('WSEnterpriseAssistantListener'))
const server: WebSocketListener = new WebSocketListener(new Logger('WebSocketListener'), configurator.dataProcessor)

const mqtt: MqttProvider = new MqttProvider(config)
const mqtt: MqttProvider = new MqttProvider(Environment.Config)
mqtt.connectBroker()

const dbFactory = new DbCreatorFactory()
Expand Down Expand Up @@ -125,8 +107,8 @@
await waitForSecretsManager(configurator.secretsManager)
})
.then(() => {
app.listen(config.web_port, () => {
log.info(`RPS Microservice Rest APIs listening on http://:${config.web_port}.`)
app.listen(Environment.Config.web_port, () => {
log.info(`RPS Microservice Rest APIs listening on http://:${Environment.Config.web_port}.`)

Check warning on line 111 in src/Index.ts

View check run for this annotation

Codecov / codecov/patch

src/Index.ts#L110-L111

Added lines #L110 - L111 were not covered by tests
})
server.connect()
serverForEnterpriseAssistant.connect()
Expand All @@ -144,8 +126,8 @@
await processServiceConfigs(consul, config)
}

if (config.consul_enabled) {
setupServiceManager(config).then(() => {
if (Environment.Config.consul_enabled) {
setupServiceManager(Environment.Config).then(() => {

Check warning on line 130 in src/Index.ts

View check run for this annotation

Codecov / codecov/patch

src/Index.ts#L130

Added line #L130 was not covered by tests
startItUp()
}).catch(err => {
log.error(`Unable to reach consul: ${err}`)
Expand Down
2 changes: 1 addition & 1 deletion src/NodeForge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class NodeForge {
}

getBags (pkcs12Pfx: forge.pkcs12.Pkcs12Pfx, filter: forge.pkcs12.BagsFilter): {
[key: string]: forge.pkcs12.Bag[]
[key: string]: forge.pkcs12.Bag[] | undefined
localKeyId?: forge.pkcs12.Bag[]
friendlyName?: forge.pkcs12.Bag[]
} {
Expand Down
62 changes: 37 additions & 25 deletions src/ProfileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
* @param {string} profileName profile to look up
* @returns {string} returns the activation to be performed
*/
public async getActivationMode (profileName: string, tenantId: string): Promise<string> {
public async getActivationMode (profileName: string, tenantId: string): Promise<string | null> {
const profile = await this.getAmtProfile(profileName, tenantId)
let activation: string
let activation: string | null = null

if (profile?.activation) {
this.logger.debug(`found activation for profile ${profileName}`)
Expand All @@ -48,15 +48,19 @@
* @param {string} profile of cira config
* @returns {string} returns the config for CIRA for a given profile
*/
public async getCiraConfiguration (profileName: string, tenantId: string): Promise<CIRAConfig> {
public async getCiraConfiguration (profileName: string | null, tenantId: string): Promise<CIRAConfig | null> {
const profile = await this.getAmtProfile(profileName, tenantId)
let ciraConfig: CIRAConfig
let ciraConfig: CIRAConfig | null = null

if (profile?.ciraConfigName && profile.ciraConfigObject) {
this.logger.debug(`found CIRAConfigObject for profile: ${profile.profileName}`)
ciraConfig = profile.ciraConfigObject
if (profile) {
if (profile.ciraConfigName && profile.ciraConfigObject) {
this.logger.debug(`found CIRAConfigObject for profile: ${profile.profileName}`)
ciraConfig = profile.ciraConfigObject
} else {
this.logger.debug(`unable to find CIRAConfig for profile ${profile.profileName}`)

Check warning on line 60 in src/ProfileManager.ts

View check run for this annotation

Codecov / codecov/patch

src/ProfileManager.ts#L59-L60

Added lines #L59 - L60 were not covered by tests
}
} else {
this.logger.debug(`unable to find CIRAConfig for profile ${profile.profileName}`)
this.logger.debug(`unable to find CIRAConfig for profile ${profileName}`)

Check warning on line 63 in src/ProfileManager.ts

View check run for this annotation

Codecov / codecov/patch

src/ProfileManager.ts#L63

Added line #L63 was not covered by tests
}

return ciraConfig
Expand All @@ -67,9 +71,9 @@
* @param {string} profileName profile name of amt password
* @returns {string} returns the amt password for a given profile
*/
public async getAmtPassword (profileName: string, tenantId: string): Promise<string> {
const profile: AMTConfiguration = await this.getAmtProfile(profileName, tenantId)
let amtPassword: string
public async getAmtPassword (profileName: string, tenantId: string): Promise<string | null> {
const profile: AMTConfiguration | null = await this.getAmtProfile(profileName, tenantId)
let amtPassword: string | null = null
if (profile) {
if (profile.generateRandomPassword) {
amtPassword = PasswordHelper.generateRandomPassword()
Expand All @@ -82,27 +86,30 @@
} else if (this.secretsManager) {
amtPassword = await this.secretsManager.getSecretFromKey(`profiles/${profileName}`, 'AMT_PASSWORD')
} else {
amtPassword = profile.amtPassword
if (profile.amtPassword) {
amtPassword = profile.amtPassword
}
}
this.logger.debug(`found amtPassword for profile ${profileName}`)
if (!amtPassword) {
this.logger.error('password cannot be blank')
throw new Error('password cannot be blank')
}
this.logger.debug(`found amtPassword for profile ${profileName}`)
return amtPassword
} else {
this.logger.error(`unable to find amtPassword for profile ${profileName}`)
}
return null

Check warning on line 102 in src/ProfileManager.ts

View check run for this annotation

Codecov / codecov/patch

src/ProfileManager.ts#L102

Added line #L102 was not covered by tests
}

/**
* @description Retrieves the amt password set in the configuration or generates a nonstatic password
* @param {string} profileName profile name of amt password
* @returns {string} returns the amt password for a given profile
*/
public async getMEBxPassword (profileName: string, tenantId: string): Promise<string> {
const profile: AMTConfiguration = await this.getAmtProfile(profileName, tenantId)
let mebxPassword: string
public async getMEBxPassword (profileName: string, tenantId: string): Promise<string | null> {
const profile: AMTConfiguration | null = await this.getAmtProfile(profileName, tenantId)
let mebxPassword: string | null = null

Check warning on line 112 in src/ProfileManager.ts

View check run for this annotation

Codecov / codecov/patch

src/ProfileManager.ts#L110-L112

Added lines #L110 - L112 were not covered by tests
if (profile) {
if (profile.generateRandomMEBxPassword) {
mebxPassword = PasswordHelper.generateRandomPassword()
Expand All @@ -115,18 +122,20 @@
} else if (this.secretsManager) {
mebxPassword = await this.secretsManager.getSecretFromKey(`profiles/${profileName}`, 'MEBX_PASSWORD')
} else {
mebxPassword = profile.mebxPassword
if (profile.mebxPassword) {
mebxPassword = profile.mebxPassword

Check warning on line 126 in src/ProfileManager.ts

View check run for this annotation

Codecov / codecov/patch

src/ProfileManager.ts#L126

Added line #L126 was not covered by tests
}
}

this.logger.debug(`found amtPassword for profile ${profileName}`)
if (!mebxPassword) {
this.logger.error('mebx password cannot be blank')
throw new Error('mebx password cannot be blank')
}
this.logger.debug(`found amtPassword for profile ${profileName}`)

Check warning on line 133 in src/ProfileManager.ts

View check run for this annotation

Codecov / codecov/patch

src/ProfileManager.ts#L133

Added line #L133 was not covered by tests
return mebxPassword
} else {
this.logger.error(`unable to find mebxPassword for profile ${profileName}`)
}
return null

Check warning on line 138 in src/ProfileManager.ts

View check run for this annotation

Codecov / codecov/patch

src/ProfileManager.ts#L138

Added line #L138 was not covered by tests
}

/**
Expand All @@ -136,8 +145,8 @@
* @returns {string} returns the MPS password for a given profile
*/
public async getMPSPassword (profileName: string, tenantId: string): Promise<string> {
const profile: AMTConfiguration = await this.getAmtProfile(profileName, tenantId)
let mpsPassword: string
const profile: AMTConfiguration | null = await this.getAmtProfile(profileName, tenantId)
let mpsPassword: string | null = null

Check warning on line 149 in src/ProfileManager.ts

View check run for this annotation

Codecov / codecov/patch

src/ProfileManager.ts#L148-L149

Added lines #L148 - L149 were not covered by tests

if (profile?.ciraConfigObject) {
mpsPassword = PasswordHelper.generateRandomPassword()
Expand All @@ -164,14 +173,17 @@
* @param {string} profile
* @returns {AMTConfiguration} returns AMTConfig object if profile exists otherwise null.
*/
public async getAmtProfile (profile: string, tenantId: string): Promise<AMTConfiguration> {
public async getAmtProfile (profile: string | null, tenantId: string): Promise<AMTConfiguration | null> {
try {
if (!profile) {
return null
}
const amtProfile: AMTConfiguration = await this.amtConfigurations.getByName(profile, tenantId)
const amtProfile: AMTConfiguration | null = await this.amtConfigurations.getByName(profile, tenantId)
if (!amtProfile) {
return null
}
// If the CIRA Config associated with profile, retrieves from DB
if (amtProfile?.ciraConfigName != null) {
if (amtProfile.ciraConfigName != null) {
amtProfile.ciraConfigObject = await this.amtConfigurations.getCiraConfigForProfile(amtProfile.ciraConfigName, tenantId)
}
// If the TLS Config associated with profile, retrieves from DB
Expand All @@ -182,7 +194,7 @@
}
}
// If the CIRA Config associated with profile, retrieves from DB
if (amtProfile?.ieee8021xProfileName != null) {
if (amtProfile.ieee8021xProfileName != null) {
amtProfile.ieee8021xProfileObject = await this.amtConfigurations.get8021XConfigForProfile(amtProfile.ieee8021xProfileName, tenantId)
}
this.logger.debug(`AMT Profile returned from db: ${amtProfile?.profileName}`)
Expand Down
Loading
Loading