# Auth API

Authentication API for accessing MAJK Core Cognito credentials and making authenticated requests to AWS/MAJK services.

## Interface

```typescript
export interface AuthAPI {
  getAccount(): Promise<SystemAccount | null>;
  getAccountsOfType(type: AccountType | '*'): Promise<SystemAccount[]>;
  getCredentials(options?: CredentialOptions): Promise<Credentials>;
  isAuthenticated(): Promise<boolean>;
}
```

## Usage

Access the auth API through the function handler context:

```typescript
.function('myFunction', {
  description: 'Example function using auth',
  input: { type: 'object', properties: {}, additionalProperties: false },
  output: { type: 'object', properties: { result: { type: 'string' } } },
  handler: async (input, ctx) => {
    // Check authentication status
    const isAuth = await ctx.majk.auth.isAuthenticated();

    if (!isAuth) {
      throw new Error('Not authenticated');
    }

    // Get current account
    const account = await ctx.majk.auth.getAccount();

    // Get credentials for AWS service calls
    const credentials = await ctx.majk.auth.getCredentials();

    return { result: 'success' };
  }
})
```

## Methods

### isAuthenticated()

Check if the user is currently authenticated with MAJK Core.

```typescript
const isAuthenticated = await ctx.majk.auth.isAuthenticated();
if (isAuthenticated) {
  // User is authenticated with Cognito
}
```

**Returns:** `Promise<boolean>` - true if authenticated

### getAccount()

Get the current system account (typically the Cognito account).

```typescript
const account = await ctx.majk.auth.getAccount();
if (account) {
  console.log('Account type:', account.type);
  console.log('Account name:', account.name);
  console.log('Expires at:', account.expiresAt);
}
```

**Returns:** `Promise<SystemAccount | null>` - Current account or null if not authenticated

### getAccountsOfType(type)

Get all accounts of a specific type.

```typescript
// Get AWS Cognito accounts
const cognitoAccounts = await ctx.majk.auth.getAccountsOfType('aws-cognito');

// Get all accounts
const allAccounts = await ctx.majk.auth.getAccountsOfType('*');
```

**Parameters:**
- `type: AccountType | '*'` - Account type filter or '*' for all

**Account Types:**
- `'aws-cognito'` - AWS Cognito accounts
- `'azure-entra'` - Azure Entra ID accounts
- `'api-key'` - API key accounts
- `'system-default'` - System default accounts

**Returns:** `Promise<SystemAccount[]>` - Array of matching accounts

### getCredentials(options?)

Get credentials for making authenticated requests to AWS/MAJK services.

```typescript
// Get current credentials
const creds = await ctx.majk.auth.getCredentials();

// Force refresh credentials
const freshCreds = await ctx.majk.auth.getCredentials({
  forceRefresh: true
});

// Get credentials for specific purpose
const serviceCreds = await ctx.majk.auth.getCredentials({
  purpose: 'bedrock-api-call'
});
```

**Parameters:**
- `options?: CredentialOptions`
  - `forceRefresh?: boolean` - Force credential refresh
  - `purpose?: string` - Purpose description for logging
  - `timeout?: number` - Request timeout in milliseconds

**Returns:** `Promise<Credentials>` - Credential object with tokens

## Credential Types

### AWS Cognito Credentials

```typescript
interface AwsCognitoCredentials {
  accountType: 'aws-cognito';
  bearerToken: string;          // For Authorization header
  aws: {
    accessKeyId: string;        // For AWS SDK
    secretAccessKey: string;
    sessionToken: string;
    region: string;
  };
  cognito: {
    idToken: string;           // Cognito identity token
    accessToken: string;       // Cognito access token
    refreshToken: string;
  };
}
```

## Common Patterns

### Making AWS Service Calls

```typescript
handler: async (input, ctx) => {
  const credentials = await ctx.majk.auth.getCredentials();

  if (credentials.accountType === 'aws-cognito') {
    const awsCreds = credentials.aws;

    // Use with AWS SDK
    const client = new SomeAWSClient({
      region: awsCreds.region,
      credentials: {
        accessKeyId: awsCreds.accessKeyId,
        secretAccessKey: awsCreds.secretAccessKey,
        sessionToken: awsCreds.sessionToken
      }
    });

    return await client.someOperation();
  }
}
```

### Making HTTP Requests to MAJK Services

```typescript
handler: async (input, ctx) => {
  const credentials = await ctx.majk.auth.getCredentials();

  const response = await fetch('https://api.majkapp.com/some-endpoint', {
    headers: {
      'Authorization': `Bearer ${credentials.bearerToken}`,
      'Content-Type': 'application/json'
    },
    method: 'POST',
    body: JSON.stringify(data)
  });

  return await response.json();
}
```

### Authentication Guard

```typescript
handler: async (input, ctx) => {
  // Check auth before proceeding
  if (!await ctx.majk.auth.isAuthenticated()) {
    throw new Error('Authentication required');
  }

  const account = await ctx.majk.auth.getAccount();
  if (!account || account.isExpired()) {
    throw new Error('Account expired or invalid');
  }

  // Proceed with authenticated operation
  return { success: true };
}
```

### Error Handling

```typescript
handler: async (input, ctx) => {
  try {
    const credentials = await ctx.majk.auth.getCredentials();
    // Use credentials...
  } catch (error) {
    ctx.logger.error('Authentication failed', {
      error: error.message,
      function: 'myFunction'
    });

    // Handle unauthenticated state
    if (error.message.includes('not authenticated')) {
      throw new Error('Please authenticate with MAJK Core');
    }

    throw error;
  }
}
```

## Best Practices

1. **Always check authentication** before accessing protected resources
2. **Cache credentials** within a single function call to avoid multiple requests
3. **Handle token expiration** gracefully with appropriate error messages
4. **Use forceRefresh** only when necessary to avoid rate limiting
5. **Log authentication errors** with context for debugging
6. **Validate credential types** before using type-specific properties

## Error Scenarios

- **Not authenticated**: `isAuthenticated()` returns false
- **No account**: `getAccount()` returns null
- **Expired credentials**: Account `isExpired()` returns true
- **Network issues**: Credential refresh may fail
- **Rate limiting**: Too many refresh requests